'use strict';
const Promise = require('bluebird');
const bcrypt = require('bcrypt');

module.exports = function(userDao) {
  const _userDao = userDao;

  const create = function(username, fullName, email, password) {
    return new Promise((resolve, reject) => {
      hashPassword(password)
        .then((hashedPassword) => {
          const userData = {
            username: username,
            fullName: fullName,
            email: email,
            password: hashedPassword,
          };
          return _userDao.create(userData);
        })
        .then(resolve)
        .catch(reject);
    });
  };

  const authenticateUser = function(emailOrUsername, password) {
    return new Promise((resolve, reject) => {
      _userDao.getByEmailOrUsername(emailOrUsername)
        .then((user) => {
          return isMatchingPassword(password, user.password)
            .then((isMatching) => {
              delete user.password;
              isMatching ? resolve(user) : reject();
            })
            .catch(reject);
        })
        .catch(reject);
    });
  }

  const hashPassword = function(password) {
    return new Promise((resolve, reject) => {
      bcrypt.hash(password, 6)
        .then(resolve)
        .catch(reject);
    });
  };

  const isMatchingPassword = function(password, hash) {
    return new Promise((resolve, reject) => {
      bcrypt.compare(password, hash)
        .then(resolve)
        .catch(reject);
    });
  };

  const getAllUsers = function(currentUser) {
    return new Promise((resolve, reject) => {
      _userDao.getAllUsers(currentUser)
        .then((users) => {
          resolve(users);
        })
        .catch(reject);
    });
  };

  const getUser = function(emailOrUsername) {
    return new Promise((resolve, reject) => {
      _userDao.getByEmailOrUsername(emailOrUsername)
        .then((user) => {
          delete user.password;
          resolve(user);
        })
        .catch(reject);
    });
  };

  const updateHandicap = function(emailOrUsername, newHandicap) {
    return new Promise((resolve, reject) => {
      _userDao.updateHandicap(emailOrUsername, newHandicap)
        .then((handicap) => {
          resolve(handicap);
        })
        .catch(reject);
    });
  };

  return {
    create: create,
    authenticateUser: authenticateUser,
    getAllUsers: getAllUsers,
    getUser: getUser,
    updateHandicap: updateHandicap,
  };
};

@@ -1448,32 +1448,215 @@
 ;%0A    %7D);%0A  %7D;%0A%0A
+  const updateUser = function(emailOrUsername) %7B%0A    _userDao.updateUser(emailOrUsername, newData)%0A      .then((user) =%3E %7B%0A        resolve(user);%0A      %7D)%0A      .catch(reject);%0A  %7D;%0A%0A
   const getAllUs
@@ -2273,24 +2273,115 @@
    _userDao.
+getByEmailOrUsername(emailOrUsername)%0A        .then((user) =%3E %7B%0A%0A        %7D)%0A      _userDao.
 updateHandic
@@ -2398,29 +2398,16 @@
 Username
-, newHandicap
 )%0A      

add method to update user