class User < ActiveRecord::Base
  devise :omniauthable,
         :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  # Adding local authentication
  # devise :database_authenticatable, :registerable,
         # :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :encrypted_password, :password_salt, :password_confirmation, :remember_me, :person_attributes, :username, :ldap_user
  
  # customize when password is required (not if user is an user of ldap or shibboleth)
  # we do this by aliasing the method that devise adds to this model when the :password module gets loaded.
  alias_method :devise_password_required?, :password_required?

  
  belongs_to :person
  accepts_nested_attributes_for :person
  
  has_many :roles
  has_many :posts
  
  validates :email, :presence => true, :uniqueness => true
  validates_associated :person

  scoped_search :in => :person, :on => [:last_name]
  
  
  class Unknown < User
    def name; "Unknown"; end
    def media; Media.none; end
    def posts; Post.none; end
  end
  
  
  # Might want this to behave differently than an unknown user?
  class Guest < User
    def name; "Unknown"; end
    def media; Media.none; end
    def posts; Post.none; end
  end
  
  
  
  def self.find_or_create_from_ldap(auth)
    user = find_or_initialize_by_username(uid_from_ldap_auth(auth))
    if user.id.nil?
      first_name_from_ldap = auth.info.first_name
      last_name_from_ldap = auth.info.last_name
      user.person = Person.find_or_initialize_by_first_name_and_last_name(first_name_from_ldap, last_name_from_ldap)
      user.person.save if user.person.id.nil?                         
      user.email = auth.info.email
      user.ldap_user = true
      user.save!
    end
    user
  end
  
  
  def self.uid_from_ldap_auth(auth)
    # omniauth ldap's uid comes back as a string of an array with one element that is a list. oy.
    auth_array = auth.uid.split(",").map{|x| x.split("=") }.flatten
    auth_hash = Hash[*auth_array]
    uid = auth_hash["uid"]
  end
  
  
  def self.find_or_create_from_shibboleth(auth)
    p auth.inspect
  end
  
  
  def self.send_activity_notifications
    # find all users who want a notification today, and send them an email about what they've missed.
    day_of_week = %w(Sun Mon Tue Wed Thu Fri Sat)[Time.now.wday]
    users_to_notify = self.where("update_schedule LIKE '%#{day_of_week}%'")
    users_to_notify.each do |user|
      # use the more recent of last_update_sent & last_signin_at
      last_update = (user.last_update_sent.nil?) ? Time.at(0) : user.last_update_sent
      last_login = (user.last_sign_in_at.nil?) ? Time.at(0) : user.last_sign_in_at
      last_update = ((last_update <=> last_login) == 1) ? last_update : last_login
      
      fresh_posts = Post.where("updated_at > '#{last_update}'")
      Notifier.recent_activity(user, fresh_posts).deliver unless fresh_posts.empty?
      user.update_column(:last_update_sent, Time.now)
      user.save
    end
  end
  
  
  def name
    person ? person.name : "unknown"
  end
  def first_name
    person ? person.first_name : "unknown"
  end
  def last_name
    person ? person.last_name : "unknown"
  end
  
  def bio
    person ? person.bio : ""
  end
  
  def to_s
    name
  end
  
  
  def encrypted_password
    super || ""
  end
  
  
  def is?(role)
    # later, we'll have different site nbrs and other roles.
    role_relation = roles.where(:site_id => 1, :name => role.to_s.capitalize)
    !role_relation.empty?
  end
  
  
  def thumbnail_url
    person.nil? ? "" : person.thumbnail_url
  end
  
  def avatar_url
    person.nil? ? "" : person.avatar_url
  end
  
  
  protected
  
    # this gets called by Devise to determine if password validation happens.
    # we don't need password validation for ldap users.
    def password_required?
      !ldap_user? && devise_password_required?
    end
  
end
