'use strict';


var utils  = require('../../utils');
var config = require('../index');

var request  = require('request');
var mongoose = require('mongoose');

// url used to access hash/crypt service
var cryptourl = config.crypto.url + ':' + config.crypto.port;

/**
 * @class      User
 * @classdesc  Mongoose model 'user'.
 *
 * @param  {object}  user           user initialization object containing the
 *                                  required fields.
 * @param  {string}  user.email     unique email address.
 * @param  {string}  user.password  a secure password.
 */
var UserSchema = module.exports = new mongoose.Schema({

	/**
	 * Email address unique to this User.
	 *
	 * @name  User#email
	 * @type  {string}
	 */
	email: {
		type:     String,
		match:    /\S+@\S+\.\S+/,
		unique:   true,
		required: true
	},

	/**
	 * Hopefully a very strong password!
	 *
	 * @name  User#password
	 * @type  {string}
	 */
	password: { type: String, required: true },

	/**
	 * JWT Bearer token.
	 *
	 * @name  User#token
	 * @type  {string}
	 */
	token: { type: String }
});

// setup transformations
if(!UserSchema.options.toJSON) UserSchema.options.toJSON = {};
if(!UserSchema.options.toObject) UserSchema.options.toObject = {};

// toJSON transformation
UserSchema.options.toJSON.transform = function(doc, ret) {

	// set the id attribute
	ret.id = doc.id;

	// remove internal attributes
	delete ret._id;
	delete ret.__v;

	// delete sensitive information
	delete ret.password;
	delete ret.token;
}

// toObject transformation is the same as toJSON
UserSchema.options.toObject.transform = UserSchema.options.toJSON.transform;

// check for duplicates
UserSchema.pre('save', function(next) {
	if(!this.isNew) {
		return next();
	}

	mongoose.model('user').count({ email: this.email }, function(err, count) {
		if(err) {
			return next(err);
		}
		if(count > 0) {
			return next(new Error('Duplicate Email'));
		}
		return next();
	});
});

// only save the hash of user's password...
UserSchema.pre('save', function(next) {
	var user = this;

	if(!user.isModified('password')) {
		return next();
	}

	var opts = {
		url: cryptourl + '/hash',
		json: {
			plain: this.password
		}
	}
	var hash = function(tries) {
		return request.post(opts, function(err, res, body) {
			if(err) {
				console.log('hash', err);
				tries = tries - 1;
				if(tries > 0) {
					console.log('retrying...');
					hash(tries);
				}
				else {
					console.log('max retries exceeded...');
					next(utils.error(503, 'Login service down'));
				}
			}
			else {
				user.password = body.hash;
				return next();
			}
		});
	}
	return hash(5);
});

/**
 * Compares given password to the user's hashed password.
 *
 * @param  {string}    password  given password
 * @param  {function}  callback  invoked on completion
 */
UserSchema.methods.comparePassword = function(password, callback) {
	var opts = {
		url: cryptourl + '/compare',
		json: {
			hash:  this.password,
			plain: password
		}
	}
	var compare = function(tries) {
		return request.post(opts, function(err, res, body) {
			if(err) {
				console.log('compare:', err);
				tries = tries - 1;
				if(tries > 0) {
					console.log('retrying...');
					compare(tries);
				}
				else {
					console.log('max retries exceeded...');
					callback(utils.error(503, 'Login service down'));
				}
			}
			else {
				callback(null, body.match);
			}
		});
	}
	return compare(5);
}

@@ -2362,32 +2362,38 @@
 %09%09%09console.log('
+hash: 
 retrying...');%0A%09
@@ -2387,24 +2387,24 @@
 rying...');%0A
-
 %09%09%09%09%09hash(tr
@@ -2436,32 +2436,38 @@
 %09%09%09console.log('
+hash: 
 max retries exce
@@ -2531,32 +2531,32 @@
 '));%0A%09%09%09%09%7D%0A%09%09%09%7D%0A
-
 %09%09%09else %7B%0A%09%09%09%09us
@@ -2545,24 +2545,87 @@
 %7D%0A%09%09%09else %7B%0A
+%09%09%09%09if(tries %3C 5) %7B%0A%09%09%09%09%09console.log('hash: succeeded');%0A%09%09%09%09%7D%0A
 %09%09%09%09user.pas
@@ -3240,16 +3240,25 @@
 le.log('
+compare: 
 retrying
@@ -3260,24 +3260,24 @@
 rying...');%0A
-
 %09%09%09%09%09compare
@@ -3320,16 +3320,25 @@
 le.log('
+compare: 
 max retr
@@ -3414,32 +3414,32 @@
 '));%0A%09%09%09%09%7D%0A%09%09%09%7D%0A
-
 %09%09%09else %7B%0A%09%09%09%09ca
@@ -3428,24 +3428,90 @@
 %7D%0A%09%09%09else %7B%0A
+%09%09%09%09if(tries %3C 5) %7B%0A%09%09%09%09%09console.log('compare: succeeded');%0A%09%09%09%09%7D%0A
 %09%09%09%09callback

Add more logging