var crypto = require('crypto')

let db = require('@config/database')
let Auth = require('@helpers/Auth')

let User = module.exports = {}

//Login a user, if that user does not exist create them
//Issues login token
User.login = (username, password) => {
	return new Promise((resolve, reject) => {

		const lowerName = username.toLowerCase();

		db.promise()
		.query('SELECT * FROM user WHERE username = ? LIMIT 1', [lowerName])
		.then((rows, fields) => {

			//Pull out user data from database results
			const lookedUpUser = rows[0][0];

			//User not found, create a new account with set data
			if(rows[0].length == 0){
				User.create(lowerName, password)
				.then(loginToken => {
					resolve(loginToken)
				})
				return
			}

			//hash the password and check for a match
			const salt = new Buffer(lookedUpUser.salt, 'binary')
			crypto.pbkdf2(password, salt, lookedUpUser.iterations, 512, 'sha512', function(err, delivered_key){
				if(delivered_key.toString('hex') === lookedUpUser.password){

					//Passback a json web token
					const token = Auth.createToken(lookedUpUser.id)
					resolve(token)

				} else {

					reject('Password does not match database')
				}
			})
		})
		.catch(console.log)

	})
}

//Create user account
//Issues login token
User.create = (username, password) => {

	//For some reason, username won't get into the promise. But password will @TODO figure this out
	const lowerName = username.toLowerCase().trim()

	return new Promise((resolve, reject) => {

		db.promise()
		.query('SELECT * FROM user WHERE username = ? LIMIT 1', [lowerName])
		.then((rows, fields) => {

			if(rows[0].length === 0){ //No users returned, create new one. Start with hashing password

				//Params for hash function
				let shasum = crypto.createHash('sha512') //Prepare Hash
				const ran = parseInt(Date.now()) //Get current time in miliseconds
				const semiRandomInt = Math.floor(Math.random()*11) //Grab a random number
				const otherRandomInt = (ran*semiRandomInt+ran)*semiRandomInt-ran //Mix things up a bit
				shasum.update(''+otherRandomInt) //Update Hasd

				const saltString = shasum.digest('hex')
				const salt = new Buffer(saltString, 'binary') //Generate Salt hash
				const iterations = 25000

				crypto.pbkdf2(password, salt, iterations, 512, 'sha512', function(err, delivered_key) {

					//Create new user object with freshly salted password
					var currentDate = new Date().toISOString().slice(0, 19).replace('T', ' ');
					var new_user = {
						username: lowerName,
						password: delivered_key.toString('hex'),
						salt: salt,
						iterations: iterations,
						last_login: currentDate,
						created: currentDate
					};

					db.promise()
					.query('INSERT INTO user SET ?', new_user)
					.then((rows, fields) => {

						if(rows[0].affectedRows == 1){

							const newUserId = rows[0].insertId
							const loginToken = Auth.createToken(newUserId)
							resolve(loginToken)

						} else {
							//Emit Error to user
							reject('New user could not be created')
						}
					})
					.catch(console.log)
				})
			} else {
				reject('Username already in use.')
			}//END user create
		})
		.catch(console.log)

		
	})
}