#coding=utf-8

class ZipdownController < ApplicationController
  #查找项目(课程)
  # before_filter :find_project_by_bid_id, :only => [:assort]
  #检查权限
  #勿删 before_filter :authorize, :only => [:assort,:download_user_homework]
  ## 200M
  MAX_DOWN_SIZE = 500 * 1024 * 1024

  include ZipService

  if RUBY_PLATFORM =~ /linux/
    require 'pdfkit'
  end

  #统一下载功能
  def download
    if User.current.logged?
      begin
        if params[:base64file]
          file = decode64(params[:base64file])
          send_file "#{OUTPUT_FOLDER}/#{file}", :filename => filename_for_content_disposition(file), :type => detect_content_type(file)
        else
          send_file "#{OUTPUT_FOLDER}/#{params[:file]}", :filename => filename_for_content_disposition(params[:filename]), :type => detect_content_type(params[:file])
        end
      rescue => e
        render file: 'public/no_file_found.html'
      end
    else
      render_403
    end
  end

  #一个作业下所有文件打包下载,只有admin和课程老师有权限
  def assort
    if params[:obj_class] == "Bid"
      bid = Bid.find params[:obj_id]
      #render_403 if User.current.allowed_to?(:as_teacher,bid.courses.first)
      zipfile = checkfileSize(bid.homeworks) {
        zip_bid bid
      }
    elsif params[:obj_class] == "Exercise"
      exercise = Exercise.where(:id => params[:obj_id]).first
      course = exercise.course
      # render_403 unless User.current.allowed_to?(:as_teacher,course)
      order,b_sort,name,group,comment,status = params[:order] || "end_at",params[:sort] || "desc",params[:name].to_s.strip || "",params[:ex_group], params[:ex_comment], params[:ex_status]
      student_id = course.student.blank? ? "(-1)" : "(" + course.student.map{|student| student.student_id}.join(",") + ")"
      if group
        group_students = course.members.where(:course_group_id => group).joins("join users on members.user_id = users.id").select{|m| m.roles.to_s.include?("Student")}

        if group_students.empty?
          student_in_group = '(-1)'
        else
          student_in_group = '(' + group_students.map{ |member| member.user_id }.join(',')  + ')'
        end
        exercise_users_list = exercise.exercise_users.where("user_id in #{student_in_group}").order("#{order} #{b_sort}")

      else
        exercise_users_list = exercise.exercise_users.where("user_id in #{student_id}").order("#{order} #{b_sort}")
      end

      unless comment.blank?
        if comment.include?('0')
          exercise_users_list = exercise_users_list.where(:subjective_score => -1)
        else
          exercise_users_list = exercise_users_list.where("subjective_score != -1")
        end
      end

      unless status.blank?
        exercise_users_list = exercise_users_list.where(:commit_status => status)
      end

      if name && name != ""
        name = name.downcase
        exercise_users_list = exercise_users_list.select{ |exercise| exercise.user.user_extensions[:student_id].to_s.downcase.include?(name) || (exercise.user[:lastname].to_s.downcase + exercise.user[:firstname].to_s.downcase).include?(name)}
      end

      zipfile = zip_user_exercise exercise, exercise_users_list.select{|exercise| exercise.commit_status = 1}

      file = decode64(zipfile[0][:base64file])
      send_file "#{OUTPUT_FOLDER}/#{file}", :filename => filename_for_content_disposition(file), :type => detect_content_type(file)
    elsif params[:obj_class] == "HomeworkCommon" || params[:obj_class] == "ShixunWork"
      homework = HomeworkCommon.find params[:obj_id]
      course = homework.course
      # render_403 unless User.current.allowed_to?(:as_teacher,course)
      name,group,comment,status = params[:name].to_s.strip || "",params[:group], params[:comment], params[:status]
      member = course.members.where(:user_id => params[:user_id]).first
      group_teacher = member.present? && member.teacher_course_groups.count > 0
      if group || group_teacher
        group_ids = group || member.teacher_course_groups.pluck(:course_group_id)
        group_students = course.members.where(:course_group_id => group_ids)
        stundet_works = homework.student_works.where(:user_id => group_students.map(&:user_id)).includes(:user => {:user_extensions => []})
      else
        stundet_works = homework.student_works.includes(:user => {:user_extensions => []})
      end

      unless comment.blank?
        has_comment_works = User.current.student_works_scores.where(:student_work_id => homework.student_works.map(&:id), :reviewer_role => [1, 2])
        student_work_ids = has_comment_works.blank? ? '(-1)' : '(' + has_comment_works.map(&:student_work_id).join(',') + ')'
        if comment.include?('0')
          stundet_works = stundet_works.where("student_works.id not in #{student_work_ids}")
        else
          stundet_works = stundet_works.where("work_status != 0 and student_works.id in #{student_work_ids}")
        end
      end

      unless status.blank?
        stundet_works = stundet_works.where(:work_status => status)
      end

      if name && name != ""
        name = name.downcase
        stundet_works = stundet_works.select{ |work| work.user.user_extensions[:student_id].to_s.downcase.include?(name) || (work.user[:lastname].to_s.downcase + work.user[:firstname].to_s.downcase).include?(name)}
      end
      if params[:obj_class] == "HomeworkCommon"
        zipfile = checkfileSize(stundet_works) {
          zip_homework_common homework, stundet_works
        }
      else
        zipfile = zip_shixun_work homework, stundet_works.select{|work| work.work_status != 0}

        file = decode64(zipfile[0][:base64file])
        send_file "#{OUTPUT_FOLDER}/#{file}", :filename => filename_for_content_disposition(file), :type => detect_content_type(file)
      end
    elsif params[:obj_class] == "GraduationTask"
      task = GraduationTask.find params[:obj_id]
      course = task.course
      name,group,comment,status,cross = params[:name].to_s.strip || "",params[:graduation_group], params[:graduation_comment], params[:graduation_status], params[:cross_limit]

      works = task.graduation_works

      # 0表示没有分组的学生,-1表示所有分组的学生
      member = course.members.where(:user_id => User.current.id).first
      group_teacher = member.present? && member.teacher_course_groups.count > 0

      if task.cross_comment && task.status == 3
        assign_work_ids = task.graduation_work_comment_assignations.where(:user_id => User.current.id).pluck(:graduation_work_id).uniq
      else
        assign_work_ids = []
      end

      if group.present?
        group_students = course.members.where(:course_group_id => group)
        # 有分组只可能是老师身份查看列表
        works = works.where(:user_id => group_students.map(&:user_id))
      elsif group_teacher
        group_ids = member.teacher_course_groups.pluck(:course_group_id)
        group_students = course.members.where(:course_group_id => group_ids)
        works = works.where(:user_id => group_students.map(&:user_id))
        if assign_work_ids.length > 0
          work_ids = works.pluck(:id) + assign_work_ids
          works = task.graduation_works.where(:id => work_ids.uniq)
        end
      else
        works = works
        if task.cross_comment && task.status == 3 && assign_work_ids.length > 0
          work_ids = works.pluck(:id) + assign_work_ids
          works = task.graduation_works.where(:id => work_ids.uniq)
        end
      end

      unless comment.blank?
        has_comment_works = GraduationWorkScore.where(:graduation_work_id => works.map(&:id), :reviewer_role => [1, 2])
        graduation_work_ids = has_comment_works.blank? ? '(-1)' : '(' + has_comment_works.map(&:graduation_work_id).join(',') + ')'
        if comment.include?('0')
          works = works.where("graduation_works.id not in #{graduation_work_ids}")
        else
          works = works.where("work_status != 0 and graduation_works.id in #{graduation_work_ids}")
        end
      end

      unless status.blank?
        works = works.where(:work_status => status)
      end

      if cross.present?
        works = works.where(:id => assign_work_ids)
      end

      if name && name != ""
        name = name.downcase
        works = works.select{ |work| work.user.user_extensions[:student_id].to_s.downcase.include?(name) || (work.user[:lastname].to_s.downcase + work.user[:firstname].to_s.downcase).include?(name)}
      end

      zipfile = checkfileSize(works) {
        zip_homework_common task, works
      }

    elsif params[:obj_class] == "Work"
      contest_work = Work.find params[:obj_id]
      render_403 if User.current.admin_of_contest?(contest_work.contest)
      zipfile = checkfileSize(contest_work.contestant_works) {
        zip_contest_work contest_work
      }
    else
      logger.error "[ZipDown#assort] ===> #{params[:obj_class]} unKown !!"
    end
    unless params[:obj_class] == "Exercise" || params[:obj_class] == "ShixunWork"
      respond_to do |format|
        format.json {
          render json: zipfile.to_json
        }
        end
    end
  end

  #下载某一学生的作业的所有文件
  def download_user_homework
    homework = HomeworkAttach.find params[:homework]
    if User.current.admin? || User.current.member_of_course?(homework.bid.courses.first)
      if homework != nil
        unless homework.attachments.empty?
          zipfile = zip_homework_by_user homework
          filename = ((homework.user.user_extensions.nil? || homework.user.user_extensions.student_id.nil?) ? "" : homework.user.user_extensions.student_id) +
            "_" + homework.user.show_name +
            "_" + homework.name + ".zip"
          send_file zipfile.file_path, :filename => filename_for_content_disposition(filename), :type => detect_content_type(zipfile.file_path) if(zipfile)
        else
          render file: 'public/no_file_found.html'
        end
      else
        render file: 'public/file_not_found.html'
      end
    else
      render_403
    end
  #rescue => e
  #  render file: 'public/file_not_found.html'
  end

  private
  #通过作业Id找到项目(课程)
  def find_project_by_bid_id
    obj_class = params[:obj_class]
    obj_id = params[:obj_id]
    obj = obj_class.constantize.find(obj_id)
    case obj.class.to_s.to_sym
      when :Bid
        @project = obj.courses[0]
    end
  end

  def checkfileSize(works)
    file_count = 0
    file_size = 0
    works.each do |work|
      file_count += work.attachments.count
      work.attachments.each do |attach|
        file_size += attach.filesize
      end
    end

    if file_size > MAX_DOWN_SIZE
      {err: -1, message: 'file size to large'}
    elsif file_count > 0
      yield if block_given?
    else
      {err: -2, :message => "no file"}
    end
  end

end