# Module Dependencies
_             = require 'underscore'
bcrypt        = require 'bcrypt'
#mongoose      = require 'mongoose'
mongooseTypes = require 'mongoose-types'
mongooseTypes.loadTypes mongoose

Schema = mongoose.Schema
Email  = mongoose.SchemaTypes.Email


# SCHEMA
User = new mongoose.Schema
  name:
    first:  { type: String, required: true }
    last:   { type: String, required: true }
  email:    { type: Email, unique: true, required: true }
  hash:     { type: String, required: true }
  salt:     { type: String, required: true }
  roles:    [String]
  created:  Date
  updated:  Date

User.virtual('name.full').get () ->
  "#{@name.first} #{@name.last}"

User.pre 'save', (next) ->
  if @isNew
    @created = @updated = new Date
  else
    @updated = new Date
  next()

# AUTHENTICATION
User.virtual('password').get(-> @_password).set (password) ->
  if password isnt ''
    @_password = password
    @salt = bcrypt.genSaltSync 10
    @hash = bcrypt.hashSync password, @salt
  else
    @invalidate('password', 'password can\'t be empty')

User.method 'verifyPassword', (password, callback) ->
  bcrypt.compare password, @hash, callback

User.static 'authenticate', (email, password, callback) ->
  @findOne {email:email}, (err, user) ->
    if err then return callback(err)
    if !user then return callback(null, false, {message: 'Unknown user!'})
    user.verifyPassword password, (err, verified) ->
      if verified
        return callback null, user, {message: 'Logged in successfully!'}
      else
        return callback null, false, {message: 'Invalid password!'}


# AUTHORIZATION
User.method 'is', (role) ->
  _.contains @roles, role

module.exports = mongoose.model 'User', User
