# Source: controller/auth.js

    'use strict';

    var passport = require('passport'),
    	merge = require('utils-merge'),
    	Utilities = require('periodicjs.core.utilities'),
    	ControllerHelper = require('periodicjs.core.controller'),
    	CoreUtilities,
    	CoreController,
    	appSettings,
    	mongoose,
    	User,
    	logger,
    	configError,
    	loginExtSettings,
    	passportController;

    /**
     * logins a user using passport's local strategy, if a user is passed to this function, then the user will be logged in and req.user will be populated
     * @param  {object} req
     * @param  {object} res
     * @return {object} reponds with an error page or sends user to authenicated in resource
     */
    var login = function (req, res, next) {
    	if (configError) {
    		next(configError);
    	}
    	else {
    		passport.authenticate('local', function (err, user, info) {
    			logger.silly('info', info);
    			if (err) {
    				logger.error(err);
    				return next(err);
    			}
    			if (!user) {
    				req.flash('error', 'invalid credentials, did you forget your password?');
    				return res.redirect(loginExtSettings.settings.authLoginPath);
    			}
    			req.logIn(user, function (err) {
    				if (err) {
    					logger.error(err);
    					return next(err);
    				}
    				if (req.session.return_url) {
    					return res.redirect(req.session.return_url);
    				}
    				else {
    					return res.redirect('/');
    				}
    			});
    		})(req, res, next);
    	}
    };

    /**
     * logs user out and destroys user session
     * @param  {object} req
     * @param  {object} res
     * @return {object} sends user to logout resource
     */
    var logout = function (req, res) {
    	req.logout();
    	req.session.destroy(function (err) {
    		if (err) {
    			logger.error(err);
    		}
    		res.redirect(loginExtSettings.settings.authLogoutPath);
    	});
    };

    /**
     * keep a user logged in for 30 days
     * @param  {object} req
     * @param  {object} res
     * @return {Function} next() callback
     */
    var rememberme = function (req, res, next) {
    	// console.log('using remember me');
    	if (req.method === 'POST' && req.url === loginExtSettings.settings.authLoginPath) {
    		if (req.body.rememberme) {
    			req.session.cookie.maxAge = 2592000000; // 30*24*60*60*1000 Rememeber 'me' for 30 days
    		}
    		else {
    			req.session.cookie.expires = false;
    		}
    	}
    	next();
    };

    /**
     * make sure a user is authenticated, if not logged in, send them to login page and return them to original resource after login
     * @param  {object} req
     * @param  {object} res
     * @return {Function} next() callback
     */
    var ensureAuthenticated = function (req, res, next) {
    	if (configError) {
    		next(configError);
    	}
    	else {
    		/* if a user is logged in, and requires to link account, update the user document with social credentials and then pass to the next express middleware */
    		if (req.isAuthenticated()) {
    			if (req.session.linkaccount === true) {
    				var updateuser = {};
    				updateuser.attributes = merge(req.user.attributes, req.session.linkaccountdata);
    				CoreController.updateModel({
    					cached: req.headers.periodicCache !== 'no-periodic-cache',
    					model: User,
    					id: req.user._id,
    					updatedoc: updateuser,
    					res: res,
    					req: req,
    					callback: function (err /* , updateduser */ ) {
    						if (err) {
    							next(err);
    						}
    						else {
    							logger.verbose('linked ', req.session.linkaccountservice, ' account for ', req.user.id, req.user.email, req.user.username);
    							req.session.linkaccount = false;
    							delete req.session.linkaccount;
    							delete req.session.linkaccountdata;
    							delete req.session.linkaccountservice;
    							next();
    						}
    					}
    				});

    				// next(new Error('cannot link '+req.session.linkaccountservice+' account'));
    				// res.redirect('/user/linkaccount?service='+req.session.linkaccountservice);
    			}
    			else if (loginExtSettings && loginExtSettings.settings.disablesocialsignin === true && req.user.accounttype === 'social-sign-in') {
    				res.redirect('/auth/user/finishregistration?reason=social-sign-in-pending');
    			}
    			else if (loginExtSettings && loginExtSettings.settings.requireusername !== false && !req.user.username) {
    				res.redirect('/auth/user/finishregistration?required=username');
    				// return next();
    			}
    			else if (loginExtSettings && loginExtSettings.settings.requireemail !== false && !req.user.email) {
    				res.redirect('/auth/user/finishregistration?required=email');
    			}
    			else {
    				return next();
    			}
    		}
    		else {
    			if (req.query.format === 'json') {
    				res.send({
    					'result': 'error',
    					'data': {
    						error: 'authentication requires '
    					}
    				});
    			}
    			else {
    				logger.verbose('controller - login/user.js - ' + req.originalUrl);
    				if (req.originalUrl) {
    					req.session.return_url = req.originalUrl;
    					res.redirect(loginExtSettings.settings.authLoginPath + '?return_url=' + req.originalUrl);
    				}
    				else {
    					res.redirect(loginExtSettings.settings.authLoginPath);
    				}
    			}
    		}
    	}
    };

    /**
     * login controller
     * @module authController
     * @{@link https://github.com/typesettin/periodic}
     * @author Yaw Joseph Etse
     * @copyright Copyright (c) 2014 Typesettin. All rights reserved.
     * @license MIT
     * @requires module:passport
     * @requires module:path
     * @requires module:passport-local
     * @requires module:passport-facebook
     * @requires module:fs-extra
     * @requires module:periodicjs.core.utilities
     * @requires module:periodicjs.core.controller
     * @requires module:periodicjs.core.extensions
     * @param  {object} resources variable injection from current periodic instance with references to the active logger and mongo session
     * @return {object}           sendmail
     */
    var controller = function (resources) {
    	logger = resources.logger;
    	mongoose = resources.mongoose;
    	appSettings = resources.settings;
    	User = mongoose.model('User');
    	CoreController = new ControllerHelper(resources);
    	CoreUtilities = new Utilities(resources);

    	// var appenvironment = appSettings.application.environment;
    	loginExtSettings = resources.app.controller.extension.login.loginExtSettings;
    	passportController = require('./passport_controller')(resources, {
    		User: User,
    		loginExtSettings: loginExtSettings,
    		passport: passport
    	});
    	passportController.serialize();
    	passportController.deserialize();
    	passport = passportController.passport;
    	passportController.usePassport();
    	return {
    		rememberme: rememberme,
    		login: login,
    		logout: logout,
    		ensureAuthenticated: ensureAuthenticated,
    		loginExtSettings: loginExtSettings,
    		passport: passport
    	};
    };

    module.exports = controller;