desc "User Score description"
task :user_score do
  puts "user_score sync."
end

namespace :user_score do
  desc "calculating user score"
  task :calculate => :environment do
    puts "truncating table...#{Rails.env}"
    UserScore.destroy_all
    puts "loading..."
    # collaboration 协同得分
    users = {}
    grades = {}
    # 发帖
    Message.includes(:author).where("parent_id IS NULL").all.each do |m|
      users[m.author.id] = users[m.author.id].to_i + 2
      project = m.project
      unless project.nil?
        if m.author.member_of?(project)
          user_grade = UserGrade.find_by_user_id_and_project_id(m.author.id, project.id)
          if user_grade.nil?
            user_grade = UserGrade.create(:user_id => m.author.id, :project_id => project.id)
          end
          grades[user_grade.id] = grades[user_grade.id].to_i + 2
        end

      end

    end
    puts ":post_message calculate Completed. collaboration users count: #{users.count}"

    # 对缺陷的留言
    Journal.includes(:user).all.each do |j|
      users[j.user.id] = users[j.user.id].to_i + 1
      project = j.project
      unless project.nil?
        if j.user.member_of?(project)
          user_grade = UserGrade.find_by_user_id_and_project_id(j.user.id, project.id)
          if user_grade.nil?
            user_grade = UserGrade.create(:user_id => j.user.id, :project_id => project.id)
          end
          grades[user_grade.id] = grades[user_grade.id].to_i + 1
        end

      end
    end
    puts ":post_issue_message calculate Completed. collaboration users count: #{users.count}"

    # 更改一次缺陷状态
    Journal.joins(:details, :user).where("#{JournalDetail.table_name}.prop_key = 'status_id'").each do |j|
      users[j.user.id] = users[j.user.id].to_i + 1
      project = j.project
      unless project.nil?
        if j.user.member_of?(project)
          user_grade = UserGrade.find_by_user_id_and_project_id(j.user.id, project.id)
          if user_grade.nil?
            user_grade = UserGrade.create(:user_id => j.user.id, :project_id => project.id)
          end
          grades[user_grade.id] = grades[user_grade.id].to_i + 1
        end

      end

    end
    puts ":change_issue_status calculate Completed. collaboration users count: #{users.count}"

    # 对留言的回复
    JournalsForMessage.includes(:user).where("m_parent_id IS NOT NULL").each do |jfm|
      users[jfm.user.id] = users[jfm.user.id].to_i + 1
    end
    puts ":reply_message calculate Completed. collaboration users count: #{users.count}"

    # 对帖子的回复
    Message.includes(:author).where("parent_id IS NOT NULL").each do |m|
      users[m.author.id] = users[m.author.id].to_i + 1
      project = m.project
      unless project.nil?
        if m.author.member_of?(project)
          user_grade = UserGrade.find_by_user_id_and_project_id(m.author.id, project.id)
          if user_grade.nil?
            user_grade = UserGrade.create(:user_id =>m.author.id, :project_id => project.id)
          end
          grades[user_grade.id] = grades[user_grade.id].to_i + 1
        end

      end
    end
    puts ":reply_posting calculate Completed. collaboration users count: #{users.count}"

    UserScore.transaction do
      users.each do |user_id, score|
        UserScore.find_or_create_by_user_id(user_id).update_attribute(:collaboration, score)
      end
    end
    puts "=== UserScore#collaboration calculate Completed. collaboration users count: #{users.count}"
    puts ""

    users.clear

    # influence 影响力得分
    #关注
    users_influence = {}
    Watcher.includes(:watchable).where("watchable_type = 'Principal'").all.each do |w|
      users_influence[w.watchable.id] = users_influence[w.watchable.id].to_i + 2
    end
    puts ":followed_by calculate Completed. influence users count: #{users_influence.count}"

    UserScore.transaction do
      users_influence.each do |user_id, score|
        UserScore.find_or_create_by_user_id(user_id).update_attribute(:influence, score)
      end
    end
    puts "=== UserScore#influence calculate Completed. influence users count: #{users_influence.count}"
    puts ""
    # skill 技术得分
    # 顶踩帖
    users_skill = {}
    PraiseTread.where("praise_tread_object_type = 'Memo' || praise_tread_object_type = 'Message'").all.each do |pt|
      obj = PraiseTread.find_object_by_type_and_id(pt.praise_tread_object_type, pt.praise_tread_object_id)
      if obj.nil?
        next
      end
      target_user = obj.author
      level = UserLevels.get_level(pt.user)#pt.user.get_level
      project = pt.project
      if pt.praise_or_tread == 0
        #踩帖
        users_skill[pt.user.id] = users_skill[pt.user.id].to_i - 2 #踩别人帖-2分
        unless project.nil?
          if pt.user.member_of?(project)
            user_grade = UserGrade.find_by_user_id_and_project_id(pt.user.id, project.id)
            if user_grade.nil?
              user_grade = UserGrade.create(:user_id =>pt.user.id, :project_id => project.id)
            end
            grades[user_grade.id] = grades[user_grade.id].to_i - 2
          end

        end
        if level == 1
          users_skill[target_user.id] = users_skill[target_user.id].to_i - 2 #帖子被一级会员踩-2分  add praise_tread
          unless project.nil?
            if target_user.member_of?(project)
              user_grade = UserGrade.find_by_user_id_and_project_id(target_user.id, project.id)
              if user_grade.nil?
                user_grade = UserGrade.create(:user_id =>target_user.id, :project_id => project.id)
              end
              grades[user_grade.id] = grades[user_grade.id].to_i - 2
            end

          end
        elsif  level == 2
          users_skill[target_user.id] = users_skill[target_user.id].to_i - 4 #帖子被二级会员踩-4分  add praise_tread
          unless project.nil?
            if target_user.member_of?(project)
              user_grade = UserGrade.find_by_user_id_and_project_id(target_user.id, project.id)
              if user_grade.nil?
                user_grade = UserGrade.create(:user_id =>target_user.id, :project_id => project.id)
              end
              grades[user_grade.id] = grades[user_grade.id].to_i - 4
            end

          end
        elsif level == 3
          users_skill[target_user.id] = users_skill[target_user.id].to_i - 6 #帖子被三级会员踩-6分  add praise_tread
          unless project.nil?
            if target_user.member_of?(project)
              user_grade = UserGrade.find_by_user_id_and_project_id(target_user.id, project.id)
              if user_grade.nil?
                user_grade = UserGrade.create(:user_id =>target_user.id, :project_id => project.id)
              end
              grades[user_grade.id] = grades[user_grade.id].to_i - 6
            end

          end
        end
      elsif pt.praise_or_tread == 1
        #顶贴
        if level == 1
          users_skill[target_user.id] = users_skill[target_user.id].to_i + 4 #帖子被一级会员顶+4分  add praise_tread
          unless project.nil?
            if target_user.member_of?(project)
              user_grade = UserGrade.find_by_user_id_and_project_id(target_user.id, project.id)
              if user_grade.nil?
                user_grade = UserGrade.create(:user_id =>target_user.id, :project_id => project.id)
              end
              grades[user_grade.id] = grades[user_grade.id].to_i + 4
            end

          end
        elsif level == 2
          users_skill[target_user.id] = users_skill[target_user.id].to_i + 6 #帖子被二级会员顶+6分  add praise_tread
          unless project.nil?
            if target_user.member_of?(project)
              user_grade = UserGrade.find_by_user_id_and_project_id(target_user.id, project.id)
              if user_grade.nil?
                user_grade = UserGrade.create(:user_id =>target_user.id, :project_id => project.id)
              end
              grades[user_grade.id] = grades[user_grade.id].to_i + 6
            end

          end
        elsif  level == 3
          users_skill[target_user.id] = users_skill[target_user.id].to_i + 8 #帖子被三级会员顶+8分  add praise_tread
          unless project.nil?
            if target_user.member_of?(project)
              user_grade = UserGrade.find_by_user_id_and_project_id(target_user.id, project.id)
              if user_grade.nil?
                user_grade = UserGrade.create(:user_id =>target_user.id, :project_id => project.id)
              end
              grades[user_grade.id] = grades[user_grade.id].to_i + 8
            end

          end
        end
      end
    end
    puts ":praised_by_user and :treaded_by_user calculate Completed. skill users count: #{users_skill.count}"
    UserScore.transaction do
      users_skill.each do |user_id, score|
        UserScore.find_or_create_by_user_id(user_id).update_attribute(:skill, score)
      end
    end
    puts "=== UserScore#skill calculate Completed. skill users count: #{users_skill.count}"
    puts ""

    # active 项目贡献得分
    users_active = {}
    # 提交代码
    Changeset.includes(:user).all.each do |changeset|
      if changeset.user.nil?
        next
      end
      users_active[changeset.user.id] = users_active[changeset.user.id].to_i + 4
      project = changeset.project
      unless project.nil?
        if changeset.user.member_of?(project)
          user_grade = UserGrade.find_by_user_id_and_project_id(changeset.user.id, project.id)
          if user_grade.nil?
            user_grade = UserGrade.create(:user_id =>changeset.user.id, :project_id => project.id)
          end
          grades[user_grade.id] = grades[user_grade.id].to_i + 4
        end

      end
    end
    puts ":push_code calculate Completed. active users count: #{users_active.count}"
    #提交文档
    Document.includes(:user).all.each do |document|
      if document.user.nil?
        next
      end
      users_active[document.user.id] = users_active[document.user.id].to_i + 4
      project = document.project
      unless project.nil?
        if document.user.member_of?(project)
          user_grade = UserGrade.find_by_user_id_and_project_id(document.user.id, project.id)
          if user_grade.nil?
            user_grade = UserGrade.create(:user_id =>document.user.id, :project_id => project.id)
          end
          grades[user_grade.id] = grades[user_grade.id].to_i + 4
        end

      end
    end
    puts ":push_document calculate Completed. active users count: #{users_active.count}"
    #提交附件
    Attachment.includes(:author).all.each do |attachment|
      #if attachment.container_id_changed?
      #  type = attachment.container_type
      #  types = %w|Document News Version Project Issue Message WikiPage|
      #  if types.include?(type)
      if attachment.author.nil?
        next
      end
      users_active[attachment.author.id] = users_active[attachment.author.id].to_i + 4
      if attachment.container.class.to_s == "Project"
        project = attachment.project
        unless project.nil?
          if attachment.author.member_of?(project)
            user_grade = UserGrade.find_by_user_id_and_project_id(attachment.author.id, project.id)
            if user_grade.nil?
              user_grade = UserGrade.create(:user_id =>attachment.author.id, :project_id => project.id)
            end
            grades[user_grade.id] = grades[user_grade.id].to_i + 4
          end

        end
      end

      #  end
      #end
    end
    puts ":push_file calculate Completed. active users count: #{users_active.count}"
    #更新完成度
    Journal.joins(:details, :user).where("#{JournalDetail.table_name}.prop_key = 'done_ratio'").each do |j|
      users_active[j.user.id] = users_active[j.user.id].to_i + 2
      project = j.project
      unless project.nil?
        if j.user.member_of?(project)
          user_grade = UserGrade.find_by_user_id_and_project_id(j.user.id, project.id)
          if user_grade.nil?
            user_grade = UserGrade.create(:user_id =>j.user.id, :project_id => project.id)
          end
          grades[user_grade.id] = grades[user_grade.id].to_i + 4
        end
      end
    end
    puts ":update_issue_ratio calculate Completed. active users count: #{users_active.count}"
    #发布缺陷
    Issue.includes(:author).all.each do |issue|
      users_active[issue.author.id] = users_active[issue.author.id].to_i + 4
      project = issue.project
      unless project.nil?
        if issue.author.member_of?(project)
          user_grade = UserGrade.find_by_user_id_and_project_id(issue.author.id, project.id)
          if user_grade.nil?
            user_grade = UserGrade.create(:user_id =>issue.author.id, :project_id => project.id)
          end
          grades[user_grade.id] = grades[user_grade.id].to_i + 4
        end

      end
    end
    puts ":post_issue calculate Completed. active users count: #{users_active.count}"


    UserScore.transaction do
      users_active.each do |user_id, score|
        UserScore.find_or_create_by_user_id(user_id).update_attribute(:active, score)
      end
    end
    puts "=== UserScore#active calculate Completed. active users count: #{users_active.count}"
    UserGrade.transaction do
      grades.each do |grade_id,score|
        grade = UserGrade.find(grade_id)
        grade.grade = score
        grade.save
      end
    end
    puts "=== UserGrid calculate Completed. UserGrids count: #{grades.count}"
  end
end

desc "create tmp file, to test"
file 'tmp/test.yml' do
  require 'yaml'
  var = {
      :name => "name",
      :age => "age",
      :agent => "agent"
  }
  File.open('tmp/test.yml', 'w') do |f|
    f.write YAML.dump({'conf' => var})
  end
end