/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

// Fire me up!

const _ = require('lodash');

module.exports = {
    implements: 'services/auth',
    inject: ['mongo', 'settings', 'errors', 'services/utils', 'services/mails']
};

/**
 * @param mongo
 * @param settings
 * @param errors
 * @param {UtilsService} utilsService
 * @param {MailsService} mailsService
 * @returns {AuthService}
 */

module.exports.factory = (mongo, settings, errors, utilsService, mailsService) => {
    class AuthService {
        /**
         * Reset password reset token for user.
         *
         * @param host Web Console host.
         * @param email - user email
         * @returns {Promise.<mongo.Account>} - that resolves account found by email with new reset password token.
         */
        static resetPasswordToken(host, email) {
            return mongo.Account.findOne({email}).exec()
                .then((user) => {
                    if (!user)
                        throw new errors.MissingResourceException('Account with that email address does not exists!');

                    if (settings.activation.enabled && !user.activated)
                        throw new errors.MissingConfirmRegistrationException(user.email);

                    user.resetPasswordToken = utilsService.randomString(settings.tokenLength);

                    return user.save();
                })
                .then((user) => mailsService.emailUserResetLink(host, user));
        }

        /**
         * Reset password by reset token.
         *
         * @param host Web Console host.
         * @param {string} token - reset token
         * @param {string} newPassword - new password
         * @returns {Promise.<mongo.Account>} - that resolves account with new password
         */
        static resetPasswordByToken(host, token, newPassword) {
            return mongo.Account.findOne({resetPasswordToken: token}).exec()
                .then((user) => {
                    if (!user)
                        throw new errors.MissingResourceException('Failed to find account with this token! Please check link from email.');

                    if (settings.activation.enabled && !user.activated)
                        throw new errors.MissingConfirmRegistrationException(user.email);

                    return new Promise((resolve, reject) => {
                        user.setPassword(newPassword, (err, _user) => {
                            if (err)
                                return reject(new errors.AppErrorException('Failed to reset password: ' + err.message));

                            _user.resetPasswordToken = undefined; // eslint-disable-line no-undefined

                            resolve(_user.save());
                        });
                    });
                })
                .then((user) => mailsService.emailPasswordChanged(host, user));
        }

        /**
         * Find account by token.
         *
         * @param {string} token - reset token
         * @returns {Promise.<{token, email}>} - that resolves token and user email
         */
        static validateResetToken(token) {
            return mongo.Account.findOne({resetPasswordToken: token}).exec()
                .then((user) => {
                    if (!user)
                        throw new errors.IllegalAccessError('Invalid token for password reset!');

                    if (settings.activation.enabled && !user.activated)
                        throw new errors.MissingConfirmRegistrationException(user.email);

                    return {token, email: user.email};
                });
        }

        /**
         * Validate activationToken token.
         *
         * @param {mongo.Account} user - User object.
         * @param {string} activationToken - activate account token
         * @return {Error} If token is invalid.
         */
        static validateActivationToken(user, activationToken) {
            if (user.activated) {
                if (!_.isEmpty(activationToken) && user.activationToken !== activationToken)
                    return new errors.AuthFailedException('Invalid email or password!');
            }
            else {
                if (_.isEmpty(activationToken))
                    return new errors.MissingConfirmRegistrationException(user.email);

                if (user.activationToken !== activationToken)
                    return new errors.AuthFailedException('This activation token isn\'t valid.');
            }
        }

        /**
         * Check if activation token expired.
         *
         * @param {mongo.Account} user - User object.
         * @param {string} activationToken - activate account token
         * @return {boolean} If token was already expired.
         */
        static isActivationTokenExpired(user, activationToken) {
            return !user.activated &&
                new Date().getTime() - user.activationSentAt.getTime() >= settings.activation.timeout;
        }

        /**
         * Reset password reset token for user.
         *
         * @param host Web Console host.
         * @param email - user email.
         * @returns {Promise}.
         */
        static resetActivationToken(host, email) {
            return mongo.Account.findOne({email}).exec()
                .then((user) => {
                    if (!user)
                        throw new errors.MissingResourceException('Account with that email address does not exists!');

                    if (!settings.activation.enabled)
                        throw new errors.IllegalAccessError('Activation was not enabled!');

                    if (user.activationSentAt &&
                        new Date().getTime() - user.activationSentAt.getTime() < settings.activation.sendTimeout)
                        throw new errors.IllegalAccessError('Too Many Activation Attempts!');

                    user.activationToken = utilsService.randomString(settings.tokenLength);
                    user.activationSentAt = new Date();

                    return user.save();
                })
                .then((user) =>  mailsService.emailUserActivation(host, user));
        }
    }

    return AuthService;
};
