const { Middleware } = require('libflitter')

class TrapUtility {
    constructor(req, res, configs) {
        this.request = req
        this.session = req.session
        this.response = res
        this.user = req.user
        this.configs = configs
    }

    async begin(trap_name, { session_only = false }) {
        if ( session_only || !this.user ) {
            this.session.trap = trap_name
        } else {
            this.user.trap = trap_name
            await this.user.save()
        }

        if ( this.config().assume_trust )
            this.request.trust.assume()
    }

    redirect() {
        if ( this.config().assume_trust )
            this.request.trust.assume()
        return this.response.redirect(this.config().redirect_to)
    }

    async end() {
        if ( this.config().assume_trust )
            this.request.trust.unassume()
        if ( this.user ) {
            this.user.trap = ''
            await this.user.save()
        }
        this.session.trap = ''
    }

    has_trap(name = '') {
        if ( name )
            return (this.user && this.user.trap === name) || this.session.trap === name
        return (this.user && this.user.trap) || this.session.trap
    }

    get_trap() {
        if ( this.session.trap ) return this.session.trap
        else if ( this.user ) return this.user.trap
    }

    trap_exists(name) {
        return !!this.configs[name]
    }

    config() {
        return this.configs[this.get_trap()]
    }

    allows(route) {
        const config = this.config()
        return route.startsWith('/assets') || config.allowed_routes.includes(route.toLowerCase().trim())
    }
}

class TrapsMiddleware extends Middleware {
    static get services() {
        return [...super.services, 'models', 'configs']
    }

    async test(req, res, next, args = {}) {
        req.trap = new TrapUtility(req, res, this.configs.get('traps.types'))

        if ( !req.trap.has_trap() ) return next()
        else if ( req.trap.allows(req.path) ) return next()
        else return req.trap.redirect()
    }
}

module.exports = exports = TrapsMiddleware
