const JwtStrategy = require("passport-jwt").Strategy;
const ExtractJwt = require("passport-jwt").ExtractJwt;
const Config = require("config");
const {pick, size} = require("lodash");
const passport = require("passport");

const options = {
    jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('jwt'),
    secretOrKey: Config.security.secret,
    algorithms: [Config.security.hash],
    session: false
};




module.exports = {
    strategy: new JwtStrategy(options, (jwt_payload, done) => {
        const user = pick(jwt_payload, ["_id", "name", "email", "tokenType"]);

        return done(null, user);
    }),


    authorize: (req, res, next) => {
        passport.authenticate("jwt", (err, user, info) => {

            if (err) {
                return next(err);
            }

            // Validate missing token
            if (info && info.message === "No access token") {
                req.error = new Error("noAccessToken")
                req.error.details = info;
                req.resStatus = 422;
                return next();
            }

            // Validate corrupted token
            if (!user) {
                // Check if header `Authorization: jwt {token}` is set properly
                if (req.headers.authorization && req.headers.authorization.indexOf("JWT ") == -1) {
                     req.error = new Error("invalidTokenFormat")
                 } else {
                     req.error = new Error("tokenExpired")
                 }
                req.resStatus = 422;
                return next();
            }

            // Validate token type
            if (user.tokenType != "access") {
                req.error = new Error("invalidTokenType")
                req.error.details = {
                    shouldBe: "access",
                    is: user.tokenType
                }
                req.resStatus = 422;
                return next();
            }

            delete user.tokenType;

            // Log the user in so user var is accessible via req.user
            req.logIn(user, err => {
                if (err) {
                    return next(err);
                }
                next();
            });
        })(req, res, next);
    }
}
