class SiteSuperUser
  include Mongoid::Document
  include Mongoid::Timestamps
  require_dependency 'bcrypt'
  begin
    require_or_load 'bcrypt/engine'
  rescue
    Object.send(:remove_const, 'BCrypt') rescue nil
    $LOADED_FEATURES.select!{|p| !p.include? 'bcrypt'}
    require 'bcrypt'
  end
  require_dependency 'active_model/secure_password'
  include ActiveModel::SecurePassword
  field :is_changed, type: Boolean, default: true
  field :old_user_name, type: String, default: ''
  field :user_name, type: String
  field :password_high_security, type: Boolean, default: false
  field :password_updated_at, type: Time
  field :password_digest, type: String
  field :old_password_digest_list, type: Array, default: []
  field :beta_tester, type: Boolean, default: true
  field :approved, type: Boolean, default: true
  belongs_to :site_server
  belongs_to :site_construct
  has_secure_password
  CurrentSite = Site.first
  PasswordValidRegex = ::Regexp.new("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})")
  CurrentSite.password_change_constrained = 5
  before_save do
    if self.user_name_changed? && self.user_name_was
      self.old_user_name = self.user_name_was if !(self.is_changed) || self.old_user_name.blank?
      self.is_changed = true
    end
  end
  before_destroy do
    if self.site_server
      self.site_server.removed_super_users << (self.old_user_name.blank? ? self.user_name :  self.old_user_name)
      self.site_server.super_user_changed = true
      self.site_server.save
    elsif self.site_construct
      self.site_construct.removed_super_users << (self.old_user_name.blank? ? self.user_name :  self.old_user_name)
      self.site_construct.super_user_changed = true
      self.site_construct.save
    end
  end
  def self.clear_changed
    self.update_all(:is_changed=>false, :old_user_name=>nil)
  end
  def clear_changed
    self.is_changed = false
    self.old_user_name = nil
    self.save
  end
  def self.generate_password_digest(password)
    if password.length < 8
      raise StandardError.new('Password too short!')
    end
    BCrypt::Password.create(password)
  end
  def old_password_digest_list_check(password)
    tmps = self.old_password_digest_list + [self.password_digest]
    tmps = tmps.compact.uniq
    if tmps.length>0
      tmp_len = self.class::CurrentSite.password_change_constrained+1
      tmp_len = tmps.length<tmp_len ? tmps.length : tmp_len
      @old_password_index = tmps[-tmp_len..-1].index{|pwd| BCrypt::Password.new(pwd)==password}
      if @old_password_index.nil?
        true
      else
        @old_password_index = -tmp_len + @old_password_index
        false
      end
    else
      true
    end
  end
  def get_attrs
    user_attrs = self.attributes
    user_attrs.except('_id', 'site_server_id', 'site_construct_id', 'is_changed', 'old_user_name')
  end
  def update_password_digest(new_password_digest)
    self.old_password_digest_list << self.password_digest if self.password_digest
    self.password_digest = new_password_digest
    self.save
  end
  def password=(value)
    if self.old_password_digest_list_check(value)
      if self.password_digest != self.old_password_digest_list[-1]
        self.password_updated_at = Time.zone.now
        if PasswordValidRegex.match(value)
          self.password_high_security = true
        else
          self.password_high_security = false
        end
        if self.class::CurrentSite.password_change_constrained
            self.old_password_digest_list << self.password_digest
        end
        self.is_changed = true
      end
      super(value)
      if !self.new_record?
        self.save
      end
    else
      unless @old_password_index == -1 # @old_password_index = -1 -> the same as current password
        self.is_changed = true
        puts "@old_password_index: #{@old_password_index}"
        self.old_password_digest_list << self.password_digest
        self.old_password_digest_list.delete_at(@old_password_index)
        super(value)
        if !self.new_record?
          self.save
        end
      end
    end
    self
  end
end