const Middleware = require('libflitter/middleware/Middleware')

/*
 * BearerToken Middleware
 * -------------------------------------------------------------
 * Put some description here!
 */
class BearerToken extends Middleware {
    static get services() {
        return [...super.services, 'models']
    }

    /*
     * Run the middleware test.
     * This method is required by all Flitter middleware.
     * It should either call the next function in the stack,
     * or it should handle the response accordingly.
     */
    async test(req, res, next, args = []){
        const Token = this.models.get('api:Token')

        const token_string = req.headers.authorization
        if ( !token_string ) return this.fail(res, )
        else if ( !token_string.startsWith('bearer ') ) return this.fail(res, 'Invalid authorization token. Prefix with "bearer".')

        try {
            const token = await Token.verify(token_string.replace('bearer ', ''))
            const user = await token.user()
            if ( !user || !token ) return this.fail(res)

            if ( Array.isArray(args) ) {
                for (const grant of args) {
                    if (!token.can(grant)) {
                        return this.fail(res)
                    }
                }
            }

            req.user = user
            req.token = token
            next()
        } catch (e) {
            return this.fail(res, String(e))
        }
    }
    
    fail(res, msg = 'Unauthorized') {
        return res.status(401).message(msg).api({})
    }
}

module.exports = exports = BearerToken
