class HomeworkCommonController < ApplicationController
  require 'net/http'
  require 'json'
  require "base64"
  layout "base_courses"

  include StudentWorkHelper
  before_filter :find_course, :only => [:index,:new,:create]
  before_filter :find_homework, :only => [:edit,:update,:alert_anonymous_comment,:start_anonymous_comment,:stop_anonymous_comment,:destroy,:start_evaluation_set,:set_evaluation_attr,:score_rule_set,:alert_forbidden_anonymous_comment,:alert_open_student_works,:open_student_works]
  before_filter :teacher_of_course, :only => [:new, :create, :edit, :update, :destroy, :start_anonymous_comment, :stop_anonymous_comment, :alert_anonymous_comment,:start_evaluation_set,:set_evaluation_attr,:score_rule_set,:alert_forbidden_anonymous_comment,:alert_open_student_works,:open_student_works]
  before_filter :member_of_course, :only => [:index]

  def index
    #unless params[:page]
    #  update_homework_time(@course.homework_commons)
    #end
    search = "%#{params[:search].to_s.strip.downcase}%"
    @new_homework = HomeworkCommon.new
    @new_homework.homework_detail_manual = HomeworkDetailManual.new
    @new_homework.course = @course
    @page = params[:page] ? params[:page].to_i + 1 : 0
    @is_teacher = User.current.logged? && (User.current.admin? || User.current.allowed_to?(:as_teacher,@course))
    if @is_teacher
      #@homeworks = @course.homework_commons.order("created_at desc").limit(10).offset(@page * 10)
      @homework_commons = @course.homework_commons.where("name like '%#{search}%'").order("created_at desc")
    else
      #@homeworks = @course.homework_commons.where("publish_time <= '#{Date.today}'").order("created_at desc").limit(10).offset(@page * 10)
      @homework_commons = @course.homework_commons.where("name like '%#{search}%' and publish_time <= '#{Date.today}'").order("created_at desc")
    end
    @is_student = User.current.logged? && (User.current.admin? || (User.current.member_of_course?(@course) && !@is_teacher))
    @is_new = params[:is_new]

    @homeworks = paginateHelper @homework_commons,10
    #设置at已读
    @homeworks.each do |homework|
      homework.journals_for_messages.each do |j|
        User.current.at_messages.unviewed('JournalsForMessage', j.id).each {|x| x.viewed!}
      end
    end

    respond_to do |format|
      format.js
      format.html
    end
  end

  #新建作业，在个人作业列表创建作业
  def new
    render_404
  end

  #新建作业，在个人作业列表创建作业
  def create
    redirect_to user_homeworks_user_path(User.current.id)
  end

  def edit
    @user = User.current
    @is_in_course = params[:is_in_course].to_i
    @course_activity = params[:course_activity].to_i
    if @is_in_course == 1 || @course_activity == 1
      respond_to do |format|
        format.html{render :layout => 'base_courses'}
      end
    else
      respond_to do |format|
        format.html{render :layout => 'new_base_user'}
      end
    end
  end

  def update
    if params[:homework_common]
      @homework.name = params[:homework_common][:name]
      @homework.description = params[:homework_common][:description]
      if params[:homework_common][:publish_time] == ""
        @homework.publish_time = Date.today
      else
        @homework.publish_time = params[:homework_common][:publish_time]
      end
      homework_detail_manual = @homework.homework_detail_manual || HomeworkDetailManual.new
      @homework.end_time = params[:homework_common][:end_time] || Time.now
      @homework.course_id = params[:course_id]
      anonymous = params[:homework_common][:anonymous_comment] ? params[:homework_common][:anonymous_comment].to_i : 0
      if anonymous != @homework.anonymous_comment
        if  anonymous == 1
          homework_detail_manual.ta_proportion = @homework.homework_type == 1 ? 1.0 : 0.4
        else
          homework_detail_manual.ta_proportion = @homework.homework_type == 1 ? 0.6 : 0.3
        end
      end

      if @homework.publish_time <= Date.today && homework_detail_manual.comment_status == 0
        homework_detail_manual.comment_status = 1
      end
      eval_start = homework_detail_manual.evaluation_start
      if eval_start.nil? || (eval_start <= @homework.end_time && homework_detail_manual.comment_status <= 1)
        homework_detail_manual.evaluation_start = @homework.end_time + 7
        homework_detail_manual.evaluation_end = homework_detail_manual.evaluation_start + 7
      end
      @homework.save_attachments(params[:attachments])
      render_attachment_warning_if_needed(@homework)

      #编程作业相关属性
      if @homework.homework_type == 2
          @homework.homework_detail_programing ||= HomeworkDetailPrograming.new
          @homework_detail_programing = @homework.homework_detail_programing
          @homework_detail_programing.language = params[:language_type].to_i
          if anonymous != @homework.anonymous_comment
            if anonymous == 1
              @homework_detail_programing.ta_proportion = 0.6
            else
              @homework_detail_programing.ta_proportion = 0.5
            end
          end

          @homework.homework_tests.delete_all
          inputs = params[:program][:input]
          if Array === inputs
            inputs.each_with_index do |val, i|
              @homework.homework_tests << HomeworkTest.new(
                  input: val,
                  output: params[:program][:output][i]
              )
            end
          end
      end

      #分组作业
      if @homework.homework_type == 3
        @homework.homework_detail_group ||= HomeworkDetailGroup.new
        @homework_detail_group = @homework.homework_detail_group
        @homework_detail_group.min_num = params[:min_num].to_i
        @homework_detail_group.max_num = params[:max_num].to_i
        @homework_detail_group.base_on_project = params[:base_on_project].to_i
      end

      @homework.anonymous_comment = params[:homework_common][:anonymous_comment] ? params[:homework_common][:anonymous_comment].to_i : 0
      if @homework.save
        homework_detail_manual.save if homework_detail_manual
        @homework_detail_programing.save if @homework_detail_programing
        @homework_detail_group.save if @homework_detail_group

        if params[:is_in_course] == "1"
          redirect_to homework_common_index_path(:course => @course.id)
        elsif params[:is_in_course] == "0"
          redirect_to user_homeworks_user_path(User.current.id)
        elsif params[:is_in_course] == "-1" && params[:course_activity] == "0"
          redirect_to user_path(User.current.id)
        elsif params[:is_in_course] == "-1" && params[:course_activity] == "1"
          redirect_to course_path(@course.id)
        end
      end
    end
  end

  def destroy
    if @homework.destroy
      respond_to do |format|
        format.html {
          if params[:is_in_course] == "1"
            redirect_to homework_common_index_path(:course => @course.id)
          elsif params[:is_in_course] == "0"
            redirect_to user_homeworks_user_path(User.current.id)
          elsif params[:is_in_course] == "-1" && params[:course_activity] == "0"
            redirect_to user_path(User.current.id)
          elsif params[:is_in_course] == "-1" && params[:course_activity] == "1"
            redirect_to course_path(@course.id)
          end
        }
      end
    end
  end

  #开启匿评
  #statue 1:启动成功，2：启动失败，作业总数大于等于2份时才能启动匿评，3:已开启匿评，请务重复开启,4:没有开启匿评的权限
  def start_anonymous_comment
    @statue = 4 and return unless User.current.admin? || User.current.allowed_to?(:as_teacher,@course)
    @statue = 5 and return if Time.parse(@homework.end_time.to_s).strftime("%Y-%m-%d") >= Time.now.strftime("%Y-%m-%d")
    if @homework_detail_manual.comment_status == 1
      student_works = @homework.student_works
      if student_works && student_works.size >= 2
        if @homework.homework_type == 3
          student_work_projects = @homework.student_work_projects.where("student_work_id is not null")
          student_work_projects.each_with_index do |pro_work, pro_index|
            n = @homework_detail_manual.evaluation_num
            n = n < student_works.size ? n : student_works.size - 1
            work_index = -1
            student_works.each_with_index do |stu_work, stu_index|
              if stu_work.id.to_i == pro_work.student_work_id.to_i
                work_index = stu_index
              end
            end
            assigned_homeworks = get_assigned_homeworks(student_works, n, work_index)
            assigned_homeworks.each do |h|
              student_works_evaluation_distributions = StudentWorksEvaluationDistribution.new(user_id: pro_work.user_id, student_work_id: h.id)
              student_works_evaluation_distributions.save
            end
          end
        else
          student_works.each_with_index do |work, index|
            user = work.user
            n = @homework_detail_manual.evaluation_num
            n = n < student_works.size ? n : student_works.size - 1
            assigned_homeworks = get_assigned_homeworks(student_works, n, index)
            assigned_homeworks.each do |h|
              student_works_evaluation_distributions = StudentWorksEvaluationDistribution.new(user_id: user.id, student_work_id: h.id)
              student_works_evaluation_distributions.save
            end
          end
        end
        @homework_detail_manual.update_column('comment_status', 2)
        @homework_detail_manual.update_column('evaluation_start', Date.today)
        @statue = 1
        # 匿评开启消息邮件通知
        send_message_anonymous_comment(@homework, m_status = 2)
        Mailer.send_mail_anonymous_comment_open(@homework).deliver
      else
        @statue = 2

    end
    else
      @statue = 3
    end
    @user_activity_id = params[:user_activity_id].to_i
    @is_in_course = params[:is_in_course].to_i
    @course_activity = params[:course_activity].to_i
  end

  #关闭匿评
  def stop_anonymous_comment
    @homework_detail_manual.update_column('comment_status', 3)
    @homework_detail_manual.update_column('evaluation_end', Date.today)
    #计算缺评扣分
    work_ids = "(" + @homework.student_works.map(&:id).join(",") + ")"
    @homework.student_works.each do |student_work|
      absence_penalty_count = student_work.user.student_works_evaluation_distributions.where("student_work_id IN #{work_ids}").count - student_work.user.student_works_scores.where("student_work_id IN #{work_ids}").count
      student_work.absence_penalty = absence_penalty_count > 0 ? absence_penalty_count * @homework_detail_manual.absence_penalty : 0
      student_work.save
    end
    # 匿评关闭消息邮件通知
    send_message_anonymous_comment(@homework, m_status = 3)
    Mailer.send_mail_anonymous_comment_close(@homework).deliver
    @user_activity_id = params[:user_activity_id].to_i
    @is_in_course = params[:is_in_course].to_i
    @course_activity = params[:course_activity].to_i
    respond_to do |format|
      format.js
    end
  end

  # 开启/关闭匿评消息通知
  def send_message_anonymous_comment(homework, m_status )
     # status 标记匿评状态 1为关闭 0为开启
     course = homework.course
     course.members.each do |m|
       @homework.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => course.id, :viewed => false, :status => m_status)
     end
  end
  #提示
  def alert_anonymous_comment
    @cur_size = 0
    @totle_size = 0
    if @homework_detail_manual.comment_status == 1
      @totle_size = @course.student.count
      @cur_size = @homework.student_works.size
    elsif @homework_detail_manual.comment_status == 2
      @homework.student_works.map { |work| @totle_size += work.student_works_evaluation_distributions.count}
      @cur_size = 0
      @homework.student_works.map { |work| @cur_size += work.student_works_scores.where(:reviewer_role => 3).count}
    end
    @percent = format("%.2f",(@cur_size.to_f / ( @totle_size == 0 ? 1 : @totle_size)) * 100)
    @user_activity_id = params[:user_activity_id].to_i
    @is_in_course = params[:is_in_course].to_i
    @course_activity = params[:course_activity].to_i
    respond_to do |format|
      format.js
    end
  end

  def alert_forbidden_anonymous_comment
    if params[:user_activity_id]
      @user_activity_id = params[:user_activity_id]
    else
      @user_activity_id = -1
    end
    @is_in_course = params[:is_in_course] if params[:is_in_course]
    @course_activity = params[:course_activity] if params[:course_Activity]
    respond_to do |format|
      format.js
    end
  end

  def open_student_works
    if @homework.is_open == 0
      @homework.update_column('is_open', 1)
    else
      @homework.update_column('is_open', 0)
    end
    @user_activity_id = params[:user_activity_id]
    @is_in_course = params[:is_in_course] if params[:is_in_course]
    @course_activity = params[:course_activity] if params[:course_Activity]
  end

  def alert_open_student_works
    if params[:user_activity_id]
      @user_activity_id = params[:user_activity_id]
    else
      @user_activity_id = -1
    end
    @is_in_course = params[:is_in_course] if params[:is_in_course]
    @course_activity = params[:course_activity] if params[:course_Activity]
    respond_to do |format|
      format.js
    end
  end

  def programing_test
    test = {language:params[:language],src:Base64.encode64(params[:src]),input:[params[:input]],output:[params[:output]]}
    @index = params[:index]
    uri = URI('http://192.168.80.21:8080/api/realtime.json')
    body = test.to_json
    res = Net::HTTP.new(uri.host, uri.port).start do |client|
      request                 = Net::HTTP::Post.new(uri.path)
      request.body            = body
      request["Content-Type"] = "application/json"
      client.request(request)
    end
    result = JSON.parse(res.body)
    @err_msg = result["compile_error_msg"]
    result["results"].each do |re|
      @result = re["status"]
    end
  end

  #启动匿评参数设置
  def start_evaluation_set
    if params[:user_activity_id]
      @user_activity_id = params[:user_activity_id]
    else
      @user_activity_id = -1
    end
    @is_in_course = params[:is_in_course]
    @course_activity = params[:course_activity].to_i
  end

  #设置匿评参数
  def set_evaluation_attr
    if @homework_detail_manual
      unless params[:evaluation_start].to_s == @homework_detail_manual.evaluation_start.to_s
        @homework_detail_manual.evaluation_start = params[:evaluation_start]
      end

      unless @homework_detail_manual.evaluation_end.to_s == params[:evaluation_end].to_s
        @homework_detail_manual.evaluation_end = params[:evaluation_end]
      end

      @homework_detail_manual.evaluation_num = params[:evaluation_num]
      @homework_detail_manual.save
      @user_activity_id = params[:user_activity_id].to_i
      @is_in_course = params[:is_in_course].to_i
      @course_activity = params[:course_activity].to_i
    end
  end

  #评分设置
  def score_rule_set
    if params[:user_activity_id]
      @user_activity_id = params[:user_activity_id]
    else
      @user_activity_id = -1
    end
    @is_in_course = params[:is_in_course]
    @course_activity = params[:course_activity].to_i
  end

  private
  #获取课程
  def find_course
    @course = Course.find params[:course]
  rescue
    render_404
  end
  #获取作业
  def find_homework
    @homework = HomeworkCommon.find params[:id]
    @homework_detail_manual = @homework.homework_detail_manual
    @homework_detail_programing = @homework.homework_detail_programing
    @homework_detail_group = @homework.homework_detail_group
    @course = @homework.course
  rescue
    render_404
  end
  #是不是课程的老师
  def teacher_of_course
    render_403 unless User.current.allowed_to?(:as_teacher,@course) || User.current.admin?
  end

  #当前用户是不是课程的成员
  def member_of_course
    render_403 unless @course.is_public==1 || User.current.member_of_course?(@course) || User.current.admin?
  end

  def get_assigned_homeworks(student_works, n, index)
    student_works += student_works
    student_works[index + 1 .. index + n]
  end

  def update_homework_time homeworks
    unless homeworks.nil?
      homeworks.each do |h|
        if h.homework_type == 3
          student_works = h.student_work_projects.where("is_leader = 1")
          time = h.updated_at
          unless student_works.nil?
            student_works.each do |s|
              project = Project.find s.project_id
              unless project.nil? && project.gpid.nil?
                project_time=project.updated_on
                project_time=ForgeActivity.where("project_id=?",project.id).last.updated_at if ForgeActivity.where("project_id=?",project.id).last
                if format_time(time) < format_time(project_time)
                  time = project_time
                end
                begin
                  # gitlab端获取默认分支
                  g = Gitlab.client
                  default_branch = g.project(project.gpid).default_branch
                  changesets = g.commits(project.gpid, :ref_name => default_branch)
                  changesets_latest_coimmit = changesets[0]
                  unless changesets[0].blank?
                    if format_time(time) < format_time(changesets_latest_coimmit.created_at)
                      time = changesets_latest_coimmit.created_at
                    end
                  end
                rescue
                  logger.error("############## ==> update homework project time")
                end
              end
            end
          end
          puts h.updated_at
          puts time
          s_time = time
          if format_time(time) > format_time(h.updated_at)
            h.update_column('updated_at', s_time)
          end
        end
      end
    end
  end
end
