require 'active_ldap'

class LdapUser < ActiveLdap::Base
  unloadable
  ldap_mapping :prefix => "", :dn_attribute => "uid",
    :classes => %w[person inetOrgPerson organizationalPerson top]

  validates_confirmation_of :password, :allow_nil => true

  attr_accessor :password, :password_confirmation

  def self.auth_source
    @auth_source
  end

  def self.auth_source=(source)
    setup_connection(
      :host => source.host,
      :port => source.port,
      :base => source.base_dn,
      :bind_dn => source.account,
      :password => source.account_password
    )

    @auth_source = source
  end

  def admin?
    login == RedmineLeSetting.admin_account
  end

  def auth_source
    self.class.auth_source
  end
  
  def login
    self[self.auth_source.attr_login]
  end

  def login=(value)
    self[auth_source.attr_login] = value
  end

  def firstname
    self[auth_source.attr_firstname]
  end

  def firstname=(value)
    self[auth_source.attr_firstname] = value
  end

  def lastname
    self[auth_source.attr_lastname]
  end

  def lastname=(value)
    self[:cn] ||= value
    self[auth_source.attr_lastname] = value
  end

  def mail
    self[auth_source.attr_mail]
  end

  def mail=(value)
    self[auth_source.attr_mail] = value
  end

  protected
  def validate
    if !password.blank? && password.size < l=Setting.password_min_length.to_i
      add_error_message(:password, :too_short, :count => l)
    end

    if mail.blank?
      add_error_message(:mail, :blank)
    elsif mail !~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/
      add_error_message(:mail, :invalid)
    end
  end

  def validate_on_create
    add_error_message(:password, :blank) if password.blank?
    add_error_message(:login, :taken) if User.find_by_login(login)
  end

  def before_save
    unless password.blank?
      self[:userPassword] = password
      if admin?
        setting = RedmineLeSetting.instance
        setting.admin_password = password
        setting.save
      end
    end
  end

  def before_destroy
    u = User.find_by_login(login)
    u.destroy unless u.nil?
  end

  private
  def add_error_message(attr, msg, options = {})
    @dummy_user ||= User.new
    self.errors.add_to_base(ActiveRecord::Error.new(@dummy_user, attr, msg, options).full_message)
  end
end
