var database = require('./database.js');
let config = require('./config.js');

module.exports = {
    /**
     * Initialize auth.
     * @param {Object} request Request object
     * @param {Object} response Response object
     * @param {Object} next Next object
     */
    init: function(request, response, next) {
        this.request = request;
        this.response = response;
        this.next = next;

        this.validateToken();
    },

    /**
     * Validate auth token.
     */
    validateToken: function() {
        let query = 'SELECT userId, ttl, created FROM salix.AccessToken WHERE id = ?';

        database.pool.query(query, [this.getToken()], (error, result) => {
            let token = result[0];

            if (error || result.length == 0)
                return this.response.status(401).send({message: 'Invalid token'});

            if (this.isTokenExpired(token.created, token.ttl))
                return this.response.status(401).send({message: 'Token expired'});

            // Set proxy host
            let proxy = config.proxy;

            if (!proxy)
                proxy = {
                    host: 'localhost',
                    port: 80
                };

            this.request.proxyHost = `http://${proxy.host}:${proxy.port}`;
            this.request.user = {
                id: token.userId,
                token: this.getToken()
            };
            this.next();
        });
    },

    /**
     * Get request token.
     * @return {String} Token
     */
    getToken: function() {
        return this.request.headers.authorization || this.request.query.token;
    },

    /**
     * Checks if the token has expired.
     * @param {String} created Creation date
     * @param {Integer} ttl Ttl seconds
     * @return {Boolean} %true if the token has expired
     */
    isTokenExpired: function(created, ttl) {
        let date = new Date(created);
        let currentDate = new Date();

        date.setSeconds(date.getSeconds() + ttl);

        if (currentDate > date)
            return true;
    }
};