var validator = require('validator');

/**
 * Local Authentication Protocol
 *
 * The most widely used way for websites to authenticate users is via a username
 * and/or email as well as a password. This module provides functions both for
 * registering entirely new users, assigning passwords to already registered
 * users and validating login requesting.
 *
 * For more information on local authentication in Passport.js, check out:
 * http://passportjs.org/guide/username-password/
 */

/**
 * Register a new user
 *
 * This method creates a new user from a specified email, username and password
 * and assign the newly created user a local Passport.
 *
 * @param {Object}   req
 * @param {Object}   res
 * @param {Function} next
 */
exports.register = function (req, res, next) {
  var email    = req.param('email')
    // , username = req.param('username')
    , password = req.param('password');

  if (!email) {
    // req.flash('error', 'Error.Passport.Email.Missing');
    return next(new Error('Error.Passport.Email.Missing'));
  }

  // if (!username) {
  //   req.flash('error', 'Error.Passport.Username.Missing');
  //   return next(new Error('No username was entered.'));
  // }

  if (!password) {
    req.flash('error', 'Error.Passport.Password.Missing');
    return next(new Error('No password was entered.'));
  }

  User.create({
    // username : username,
    email    : email
  }, function (err, user) {
    if (err) {
      // if (err.code === 'E_VALIDATION') {
      //   if (err.invalidAttributes.email) {
      //     req.flash('error', 'Error.Passport.Email.Exists');
      //   } else {
      //     req.flash('error', 'Error.Passport.User.Exists');
      //   }
      // }

      return next(err);
    }

    Passport.create({
      protocol : 'local'
    , password : password
    , user     : user.id
    }, function (err, passport) {
      if (err) {
        // if (err.code === 'E_VALIDATION') {
        //   req.flash('error', 'Error.Passport.Password.Invalid');
        // }

        return user.destroy(function (destroyErr) {
          next(destroyErr || err);
        });
      }

      next(null, user);
    });
  });
};

/**
 * Assign local Passport to user
 *
 * This function can be used to assign a local Passport to a user who doens't
 * have one already. This would be the case if the user registered using a
 * third-party service and therefore never set a password.
 *
 * @param {Object}   req
 * @param {Object}   res
 * @param {Function} next
 */
exports.connect = function (req, res, next) {
  var user     = req.user
    , password = req.param('password');

  Passport.findOne({
    protocol : 'local'
  , user     : user.id
  }, function (err, passport) {
    if (err) {
      return next(err);
    }

    if (!passport) {
      Passport.create({
        protocol : 'local'
      , password : password
      , user     : user.id
      }, function (err, passport) {
        next(err, user);
      });
    }
    else {
      next(null, user);
    }
  });
};

/**
 * Validate a login request
 *
 * Looks up a user using the supplied identifier (email) and then
 * attempts to find a local Passport associated with the user. If a Passport is
 * found, its password is checked against the password supplied in the form.
 *
 * @param {Object}   req
 * @param {string}   identifier
 * @param {string}   password
 * @param {Function} next
 */
exports.login = function (req, identifier, password, next) {
  var isEmail = validator.isEmail(identifier)
    , query   = {};

  // if (isEmail) {
    query.email = identifier;
  // }
  // else {
  //   query.username = identifier;
  // }

  User.findOne(query, function (err, user) {
    if (err) {
      return next(err);
    }

    if (!user) {
      // if (isEmail) {
        //req.flash('error', 'Error.Passport.Email.NotFound');
      // } else {
        // req.flash('error', 'Error.Passport.Username.NotFound');
      // }

      return next(new Error('Error.Passport.Email.NotFound'), false);
    }
    // Passport.findOne({
    //   protocol : 'local'
    // , user     : user.id
    // }, function (err, passport) {
    //   if (passport) {
        user.validatePassword(password, function (err, res) {
          if (err) {
            return next(err);
          }

          if (!res) {
            //req.flash('error', 'Error.Passport.Password.Wrong');

            return next(new Error('Error.Passport.Password.Wrong'), false);
          } else {
            return next(null, user);
          }
        });
    //   }
    //   else {
    //     //req.flash('error', 'Error.Passport.Password.NotSet');
    //     return next(new Error('Error.Passport.Password.NotSet'), false);
    //   }
    // });
  });
};
