# encoding: utf-8
# REDO: 创建版本库权限控制
class ShixunsController < ApplicationController
  layout 'base_shixun'
  before_filter :require_login, :except => [:ghook, :download_file, :show, :index]
  before_filter :check_authentication, :except => [:ghook, :download_file, :show, :index, :operation]
  before_filter :find_shixun, :except => [ :index, :new, :create, :index, :search, :shixun_courses, :new_disscuss, :shixun_migrate, :qrcode, :download_file, :departments, :get_mirror_script, :send_message_to_administrator]

  skip_before_filter :verify_authenticity_token, :only => [:ghook, :download_file]
  before_filter :view_allow, :only => [:collaborators, :propaedeutics, :shixun_discuss, :ranking_list]
  before_filter :require_manager, :only => [ :settings, :add_script, :publish, :collaborators_delete, :shixun_members_added, :add_collaborators, :update, :destroy]
  before_filter :validation_email, :only => [:new]
  #before_filter :require_manager, :only => [:destroy]
  # 移动云ToC模式权限控制
  # before_filter :ecloud_auth, :except => [:show, :index]

  include ApplicationHelper
  include ShixunsHelper
  CODES = %W(2 3 4 5 6 7 8 9 A B C D E F G H J K L N M O P Q R S T U V W X Y Z)
  DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)


  # 实训二维码生成器(android编译成功后,game的picture_path会返回中间层的workspace, workspace+关卡学院文件路径就是文件所在的路径)
  def qrcode
    @type == "qrcode"
    game = Game.find(params[:game_id])
    workspace = game.picture_path
    game_challenge = game.challenge
    qr = RQRCode::QRCode.new("#{Setting.host_name}/shixuns/download_file?file_name=#{workspace}/#{game_challenge.picture_path}/manual-ok.apk", :size => 10, :level => :h)
    @qrcode_str = Base64.encode64( qr.to_img.resize(400,400).to_s )
    respond_to do |format|
      format.js
    end
  end

  # 二维码扫描下载
  def download_file
    file_path = params[:file_name]
    send_file "#{Rails.root}/#{file_path}", :filename => "#{file_path}",
              :type => 'shixun',
              :disposition => 'attachment'    #inline can open in browser
  end

  # 获取版本库文件目录
  def search_file_list
    path = params[:path]
    @path = to_path_param(path)
    g = Gitlab.client
    @dir = g.trees(@shixun.gpid, :path => @path).map{|tree|[tree.type, (@path.blank? ? tree.name : "#{@path}"+"/"+tree.name )]}
    logger.info("dir is ##{@dir}")
    respond_to do |format|
      format.js
    end
    # render :json => {:dir => @dir}
  end

  def achieve_ways
    @repository = @shixun.repository
    @entries = @repository.entries(@path, @rev)
    # @entries = Gitlab.client.trees(@shixun.gpid).map{|tree| tree.name}
  end

  def statistics_students
    pub_shixun = ApplyAction.where(:container_type => "ApplyShixun", :status => 1, :container_id => @shixun.id).last
    if pub_shixun.present?
      updated_at = pub_shixun.updated_at
      admin_ids = User.where(:admin => 1).blank? ? "(-1)" : "(" + User.where(:admin => 1).map(&:id).join(",") + ")"
      @statistics = @shixun.myshixuns.where("user_id not in #{admin_ids}").select{|myshixun| myshixun.updated_at > updated_at}
      @statistic_ids = @statistics.map(&:id)
      @statistics = Myshixun.where(:id => @statistic_ids).order("created_at desc")
      #@statistics = @shixun.myshixuns.where("created_at > #{updated_at}").order("created_at desc")
      @complete_myshixun = Myshixun.where(:id => @statistics, :status => 1)
      @complete_myshixun_count = @complete_myshixun.size
      @complete_myshixun.each do |myshixun|
        myshixun[:s_score] = myshixun.total_score
        myshixun[:s_spend_time] = myshixun.total_spend_time
        myshixun[:s_accuracy] = myshixun.total_accuracy
        myshixun[:s_done_time] = myshixun.done_time
      end
      @complete_myshixun = @complete_myshixun.sort do |a, b|
        [b[:s_score], a[:s_spend_time], b[:s_accuracy], a[:s_done_time]] <=> [a[:s_score], b[:s_spend_time], a[:s_accuracy], b[:s_done_time]]
      end
      @complete_myshixun = @complete_myshixun[0, 10]
      @statistics_count =  @statistics.size
      @statistics = @statistics.limit(10)
    end
  end

  # 学员统计中的关卡统计
  def challenge_statistics
    @challenge = @shixun.challenges.where(:id => params[:c]).first
    if @challenge
      pub_shixun = ApplyAction.where(:container_type => "ApplyShixun", :status => 1, :container_id => @shixun.id).last
      if pub_shixun.present?
        updated_at = pub_shixun.updated_at
        admin_ids = User.where(:admin => 1).blank? ? "(-1)" : "(" + User.where(:admin => 1).map(&:id).join(",") + ")"
        myshixuns = @shixun.myshixuns.where("user_id not in #{admin_ids}").select{|myshixun| myshixun.updated_at > updated_at}
        @statistics = @challenge.games.where(:myshixun_id => myshixuns.map(&:id), :status => 2).select("games.*, (unix_timestamp(games.end_time)-unix_timestamp(games.open_time)) as spend_time").reorder("final_score desc, spend_time asc, accuracy desc, end_time asc")
        @statistics_count =  @statistics.size
        @statistics = paginateHelper @statistics, 20
        @page = params['page'] || 1
      end
    end
  end

  # 学员统计中的通关排行榜
  def ranking_list
    pub_shixun = ApplyAction.where(:container_type => "ApplyShixun", :status => 1, :container_id => @shixun.id).last
    if pub_shixun.present?
      updated_at = pub_shixun.updated_at
      admin_ids = User.where(:admin => 1).blank? ? "(-1)" : "(" + User.where(:admin => 1).map(&:id).join(",") + ")"
      @complete_myshixun = @shixun.myshixuns.includes(:user, :games => [:challenge]).where("user_id not in #{admin_ids} and status = 1").select{|myshixun| myshixun.updated_at > updated_at}
      #@complete_myshixun = Myshixun.where(:id => statistics.map(&:id), :status => 1)
      @complete_myshixun_count = @complete_myshixun.size
      @complete_myshixun.each do |myshixun|
        myshixun[:s_score] = myshixun_exp myshixun
        myshixun[:s_spend_time] = myshixun_spend_time myshixun
        # myshixun[:s_accuracy] = myshixun_accuracy myshixun
        # myshixun[:s_done_time] = myshixun_done_time myshixun
      end
      # @complete_myshixun = @complete_myshixun.sort do |a, b|
      #   [b[:s_score], a[:s_spend_time], b[:s_accuracy], a[:s_done_time]] <=> [a[:s_score], b[:s_spend_time], a[:s_accuracy], b[:s_done_time]]
      # end
      @complete_myshixun = @complete_myshixun.sort do |a, b|
        [b[:s_score], a[:s_spend_time]] <=> [a[:s_score], b[:s_spend_time]]
      end
      @complete_myshixun = @complete_myshixun[0..9]
    end
  end

  # 学员统计中的学员列表
  def trainee_list
    pub_shixun = ApplyAction.where(:container_type => "ApplyShixun", :status => 1, :container_id => @shixun.id).last
    if pub_shixun.present?
      updated_at = pub_shixun.updated_at
      admin_ids = User.where(:admin => 1).blank? ? "(-1)" : "(" + User.where(:admin => 1).map(&:id).join(",") + ")"
      @statistics = @shixun.myshixuns.where("user_id not in #{admin_ids}").select{|myshixun| myshixun.updated_at > updated_at}
      @statistics = @statistics.map(&:id)
      @statistics = Myshixun.where(:id => @statistics).order("created_at desc")
      @statistics_count =  @statistics.size
      @page = params['page'] || 1
      @statistics = paginateHelper @statistics, 20
    end
  end

  # push代码的时候会触发gitlab hook
  def ghook
    # shixun_modify_status_without_publish(@shixun, 1)
    render :json => {status: "success"}
  end

  # 注意:shixun_id 格式 /shixun_migrate?shixun_id=100
  # 注意:language 格式 /shixun_migrate?language="Java,Python"
  def shixun_migrate
    unless User.current.admin?
      render_403
      return
    end
    shixun_tomcat = Redmine::Configuration['shixun_tomcat']
    if params[:language]
      language = params[:language].split("/")
      logger.info(language)
      shixuns = Shixun.where(:language => language)
    elsif params[:shixun_id]
      shixuns = Shixun.where(:id => params[:shixun_id])
    else
      shixuns = Shixun.all
    end
    if shixuns.present?
      shixuns.each do |shixun|
        begin
          logger.info("shixun id is #{shixun.id}")
          tpiList =[]
          gameInfo = shixun.gameInfo
          myshixuns = shixun.myshixuns
          if myshixuns.present?
            myshixuns.each do |myshixun|
              logger.info("tpiID is #{myshixun.id}")
              tpiID = myshixun.id
              instanceGitURL = gitlab_url myshixun
              logger.info("instanceGitURL is #{instanceGitURL}")
              tpiList << {:tpiID => tpiID, :instanceGitURL => instanceGitURL}
              logger.info("###############{tpiList.to_json unless tpiList.blank?}")

              logger.info("************#{tpiList}")
            end
          end
          tpiList = Base64.urlsafe_encode64(tpiList.to_json) unless tpiList.blank?
          params = {:gameInfo => "#{gameInfo}", :tpiList => "#{tpiList}" }
          logger.info("params is #{params}")
          uri = "#{shixun_tomcat}/bridge/dataTransfer/transfer"
          logger.info("uri is #{uri}")
          res = uri_exec uri, params
          logger.info("=====res is #{res['code']}")
          render :json => {:result => "success"}
        rescue Exception => e
          logger.info("error ====> #{e.message}")
        end
      end
    end
  end


  # 向管理员发私信
  def send_message_to_administrator
    # notes = User.current.show_name.to_s + " 申请了新镜像:<a href='javascript:void(0);'>#{params[:notes]}</a>"
    # JournalsForMessage.create(
    #     :jour_id => 1,
    #     :jour_type => "Principal",
    #     :user_id => User.current.id,
    #     :reply_id => 0,
    #     :is_readed => 0,
    #     :private => 1,
    #     :notes => notes
    # )
    Tiding.create(:user_id => 1, :trigger_user_id => User.current.id, :container_type => "SendMessage", :extra => params[:notes], :viewed => 0, :tiding_type => "Apply")
    render :json => {success: "true"}
  end

  def shixun_test
    jenkins_shixuns = Redmine::Configuration['jenkins_shixuns']
    uri = URI("#{jenkins_shixuns}/jenkins-exec/webssh/getConnectInfo")
    user_id = User.current.id
    params = {userID:user_id}
    res = uri_exec uri, params
    render :json => {data:"succesed"}
  end

  def delete_shixun_test
    jenkins_shixuns = Redmine::Configuration['jenkins_shixuns']
    uri = URI("#{jenkins_shixuns}/jenkins-exec/webssh/deleteSSH")
    user_id = User.current.id
    params = {userID:user_id}
    res = uri_exec uri, params
    render :json => {data:"succesed"}
  end

  def game_webssh

  end

  def entry_edit
    g = Gitlab.client
    @path = params[:path]
    @rev = params[:rev]
    file_content = g.files(@shixun.gpid, @path, @rev).content
    @content = tran_base64_decode64(file_content)

    respond_to do |format|
      format.js
    end
  end

  def entry_update
    g = Gitlab.client
    @path = params[:path]
    @rev = params[:rev]
    @content = params[:content]
    code_file = g.edit_file(@shixun.gpid, User.current.login, :content => params[:content], :file_path => @path, :branch_name => @rev, :commit_message => "file update")
    # if @shixun.try(:status).to_i < 2
    # shixun_modify_status_without_publish(@shixun, 1)
    # end
    @shixun.myshixuns.update_all(:system_tip => 0)
    if code_file.message
      @error_message = code_file.message
    end
    respond_to do |format|
      format.js
    end
  end

  def shixun_monitor
    # monitor_filter
    # if @had_exec
    #   @tpm = Myshixun.where(:user_id => User.current, :shixun_id => @shixun).first
    # end
    #
    # respond_to do |format|
    #   format.js
    # end
  end

  def statistics
    @challenges = @shixun.challenges
    @top_students = @shixun.myshixuns.where(:status => 1)
    myshixuns = @shixun.myshixuns.includes(:games)
    @latest_myshixuns = myshixuns.order("created_at desc").limit(4)
  end

  def autocompletion

  end

  def edit_md
    #render :layout => false
  end

  # 首页实训导航点击时,type参数
  def index
    @type = params[:type]
    @status = [["全部状态", 0], ["已发布", 2], ["未发布", 1], ["已关闭", 3]]
    @diff = ["全部难度", "初级学员", "中级学员", "高级学员", "顶级学员"]
    @repertoires = Repertoire.includes(sub_repertoires: [:tag_repertoires]).order("updated_at asc")
    if @type.present?
      id = params[:id].to_i
      case @type
        when 'rep'
          rep = Repertoire.find id
          sub_id = rep.sub_repertoires.map(&:id)
          tag = TagRepertoire.where(:sub_repertoire_id => sub_id)
          @rep_active = rep.id # 页面样式、和首页跳转搜索需要
          @search_name = ""
        when 'sub'
          sub = SubRepertoire.find id
          tag = TagRepertoire.where(:sub_repertoire_id => sub)
          @rep_active = sub.repertoire.id
          @sub_acive = sub.id # 页面样式、和首页跳转搜索需要
          @search_name = "#{sub.name}"
        when 'tag'
          tag = TagRepertoire.find id
          sub = tag.sub_repertoire
          @rep_active = sub.repertoire.id
          @sub_active = sub.id
          @tag_active = tag.id # 页面样式、和首页跳转搜索需要
          @search_name = "#{sub.name} / #{tag.name}"
      end
      shixun_id = ShixunTagRepertoire.where(:tag_repertoire_id => tag).map(&:shixun_id)
      @shixuns = Shixun.select([:id, :name, :user_id, :challenges_count, :visits, :status, :myshixuns_count,
                                :trainee, :use_scope, :identifier, :image_text, :averge_star])
                     .where(:id => shixun_id, :hidden => 0).where("status != -1")
                     .includes(:challenges, :schools, :shixun_members, :users).order("status = 2 desc, publish_time asc")
    else
      @shixuns = Shixun.select([:id, :name, :user_id, :challenges_count, :visits, :status, :myshixuns_count,
                                :trainee, :use_scope, :identifier, :image_text, :averge_star])
                     .where("status != ? and hidden = ?", -1, 0).includes(:challenges, :schools, :shixun_members, :users)
                     .order("status = 2 desc, publish_time asc")
    end
    # # 依据tag和语言推荐实训,如果tag不够,则依据语言推荐;语言不够,则取系统的三个
    # @recommend_shixuns = Shixun.find_by_sql("select challenge_id from challenge_tags where name like
    #                     CONCAT('%',(select name from challenge_tags where challenge_id in (select id from challenges where shixun_id=61)),'%')")

    @obj_count = @shixuns.count
    @limit = 16
    @is_remote = true
    @obj_pages = Paginator.new @obj_count, @limit, params['page'] || 1
    @offset ||= @obj_pages.offset
    @shixuns = paginateHelper @shixuns, @limit
    respond_to do |format|
      format.js
      format.html{render :layout => "base_edu"}
    end
  end

  # params
  # repertoire:大类别; #sub_repertoire:子类别; #tag_repertoire 实训标签;
  # status:实训状态; diff:实训难度; search: 搜索条件; order:排序; sort: 升序, 降序
  def search
    repertoire = params[:repertoire]
    sub_repertoire = params[:sub_repertoire]
    tag_repertoire = params[:tag_repertoire]
    status = params[:status].to_i
    diff = params[:diff].to_i
    search = params[:search].try(:strip)
    order = params[:order]
    bsort = params[:sort]
    hidden_learn = params[:hidden_learn]
    logger.info("######params: #{params}")
    diff = (diff == 0 ? [1,2,3,4] : diff) # diff = 0表示搜索所有
    filter_status = order == "created_at" || order == "myshixuns_count" ? [2, 3] : [0, 1, 2, 3]
    status = if status == 0
               filter_status & [0, 1, 2 ,3] # 所有状态
             elsif status == 1
               filter_status & [0, 1] # 未发布
             else
               filter_status & [status]
             end
    shixun_id = if tag_repertoire.present?
                  tag = TagRepertoire.find(tag_repertoire)
                  ShixunTagRepertoire.where(:tag_repertoire_id => tag).map(&:shixun_id)
                elsif sub_repertoire.present?
                  sub = SubRepertoire.find(sub_repertoire)
                  ShixunTagRepertoire.where(:tag_repertoire_id => sub.tag_repertoires).map(&:shixun_id)
                elsif repertoire.present?
                  rep = Repertoire.find(repertoire)
                  tag_id = TagRepertoire.where(:sub_repertoire_id => rep.sub_repertoires).map(&:id)
                  ShixunTagRepertoire.where(:tag_repertoire_id => tag_id).map(&:shixun_id)
                else
                  Shixun.select([:id]).map(&:id)
                end

    # "我的"实训
    if order == "mine"
      my_shixun_ids = User.current.shixun_members.map(&:shixun_id) + User.current.myshixuns.map(&:shixun_id)
      shixun_id = shixun_id & my_shixun_ids
    end

    @shixuns = Shixun.select([:id, :name, :user_id, :challenges_count, :visits, :status, :myshixuns_count, :trainee, :use_scope, :identifier, :image_text, :averge_star]).where(:id => shixun_id, :hidden => 0, :trainee => diff, :status => status).includes(:challenges, :schools, :shixun_members, :users)

    if search.present?
      search_users_id = User.select([:id]).where("concat(lastname, firstname) like '%#{search}%'")
      search_users_id = search_users_id.blank? ? "(-1)" : "(" + search_users_id.map{|sc| sc.id}.join(',') + ")"
      search_shixun_ids = Challenge.where("subject like '%#{search}%'").pluck(:shixun_id).uniq
      search_shixun_ids = search_shixun_ids.blank? ? "(-1)" : "(" + search_shixun_ids.join(",") + ")"
      fuzzy_searchs = search.split(" ").join("%")
      @shixuns = @shixuns.where("name like ? or user_id in #{search_users_id} or id in #{search_shixun_ids}", "%#{fuzzy_searchs}%")
    end

    if hidden_learn.present?
      shixun_id = User.current.shixuns.map(&:id)
      my_shixun_id = Myshixun.where(:user_id => User.current.id).map(&:shixun_id)
      not_shixun_id = shixun_id + my_shixun_id
      not_shixun_id = not_shixun_id.size > 0 ? "(" + not_shixun_id.join(",") + ")" : "(-1)"
      @shixuns = @shixuns.where("id not in #{not_shixun_id}") if shixun_id.present?
    end

    if order == "mine"
      @shixuns = @shixuns.order("created_at #{bsort}")
    else
      @shixuns = @shixuns.order("shixuns.status = 2 desc, #{order} #{bsort}")
    end
    @obj_count = @shixuns.count
    @limit = 16
    @is_remote = true
    @obj_pages = Paginator.new @obj_count, @limit, params['page'] || 1
    @offset ||= @obj_pages.offset
    @shixuns = paginateHelper @shixuns, @limit

    respond_to do |format|
      format.js
    end
  end

  def propaedeutics
    respond_to do |format|
      format.html
    end
  end

  def update_propaedeutics
    if request.get?
      respond_to do |format|
        format.html
      end
    else
      @shixun = Shixun.where(:identifier => params[:id]).first
      @shixun.update_attribute("propaedeutics", params[:shixun][:propaedeutics])
      redirect_to propaedeutics_shixun_path(@shixun)
    end
  end

  def collaborators
    @collaborators = @shixun.shixun_members.reorder("role = 1 desc, created_at asc")
    @collaborators_count = @collaborators.size
    @limit = 10
    respond_to do |format|
      format.js
      format.html
    end
  end

  def collaborators_delete
    user_id = params[:c_id]
    gid = User.find(user_id).try(:gid)
    shixun_member = ShixunMember.where(:user_id => user_id, :shixun_id => @shixun.id, :role => 2).first
    shixun_member.delete
    g = Gitlab.client
    unless gid.nil?
      g.remove_team_member(@shixun.gpid, gid)
    end
    @collaborators = @shixun.shixun_members.reorder("role = 1 desc, created_at asc")
    @collaborators_count = @collaborators.count
    @limit = 10
    respond_to do |format|
      format.js
    end
  end

  # 已存在的成员不添加
  def add_collaborators
    if !params[:search].nil?
      member_ids = "(" + @shixun.shixun_members.map(&:user_id).join(',') +  ")"
      condition = "%#{params[:search].strip}%".gsub(" ","")
      @users = User.where("id not in #{member_ids} and status = 1 and LOWER(concat(lastname, firstname, login, mail, nickname)) LIKE '#{condition}'").includes(:user_extensions)
    end
    respond_to do |format|
      format.js
    end
  end

  # 事务处理,保证Trustie与Gitlab数据同步
  def shixun_members_added
    ActiveRecord::Base.transaction do
      begin
        unless params[:membership][:user_ids].blank?
          memberships = params[:membership][:user_ids]
          memberships.each do |member|
            user = User.find(member)
            s = Trustie::Gitlab::Sync.new
            if user.gid.present?
              gid = user.gid
            else
              guser = s.sync_user(user)
              gid = guser.id
            end
            ShixunMember.create!(:user_id => member, :shixun_id => @shixun.id, :role => 2)
            u = s.g.add_team_member(@shixun.gpid, gid, 40)  # 3代表角色master
            if u.blank?
              raise("同步Gitlab数据失败")
            end
          end
          respond_to do |format|
            format.js{redirect_to collaborators_shixun_path(@shixun)}
          end
        end
      rescue Exception => e
        logger.error(e)
        raise ActiveRecord::Rollback
      end
    end
  end

  def change_manager
    if request.get?
      @collaborators = @shixun.shixun_members.where("user_id != #{@shixun.user_id}")
    else
      if params[:choosemanager]
        man_member = ShixunMember.where(:shixun_id => @shixun.id, :user_id => @shixun.user_id).first
        cha_member = ShixunMember.find params[:choosemanager]
        if man_member && cha_member
          man_member.update_attributes(:role => 2)
          cha_member.update_attributes(:role => 1)
          @shixun.update_attributes(:user_id => cha_member.user_id)
        end
        redirect_to collaborators_shixun_path(@shixun)
      end
    end
  end

  # gameID 及实训ID
  # status:  0 , 1 申请过, 2,实训关卡路径未填, 3 实训标签未填, 4 实训未创建关卡
  def publish
    @status = 0
    @position = ""
    begin
      if @shixun.challenges.count == 0
        @status = 4
      else
        @shixun.challenges.each do |challenge|
          if challenge.challenge_tags.count == 0
            @status = 3
            @position = (@position == "" ? @position : (@position + ",")) + challenge.position.to_s + "关"
          end
        end
        unfinish_challenge = @shixun.challenges.where(:st => 0, :path => nil)
        if unfinish_challenge.count > 0 && !@shixun.is_choice_type
          @status = 2
          @pos = []
          unfinish_challenge.each do |challenge|
            @pos << challenge.position
          end
          @pos = @pos.join(",")
        end
      end
      if @status == 0
        @shixun.update_attributes!(:status => 1)
        apply = ApplyAction.where(:container_type => "ApplyShixun", :container_id => @shixun.id).order("created_at desc").first
        if apply && apply.status == 0
          @status = 0
        else
          ApplyAction.create(:container_type => "ApplyShixun", :container_id => @shixun.id, :user_id => User.current.id, :status => 0)
          begin
            status = Trustie::Sms.send(mobile: '18711011226', send_type:'publish_shixun' , name: '管理员')
          rescue => e
            Rails.logger.error "发送验证码出错: #{e}"
          end
          @status = 1
        end
      end
    rescue Exception => e
      logger.error("pushlish game #{e}")
      respond_to do |format|
        format.js
      end
    end
  end

  def apply_publish
    apply = ApplyAction.where(:container_type => "ApplyShixun", :container_id => @shixun.id).last
    if apply && apply.status == 0
      @status = 0
    else
      ApplyAction.create(:container_type => "ApplyShixun", :container_id => @shixun.id, :user_id => User.current.id, :status => 0)
      # notes = User.current.show_name.to_s + " 申请发布实训:<a href='#{shixun_path(@shixun)}'>#{@shixun.name}</a>"
      # JournalsForMessage.create(:jour_id => 1, :jour_type => 'Principal', :user_id => User.current.id, :notes => notes, :private => 1, :reply_id => 0)
      @shixun.update_column('status', 1)
      @status = 1
    end
  end

  def cancel_publish
    apply = ApplyAction.where(:container_type => "ApplyShixun", :container_id => @shixun.id).order("created_at desc").first
    if apply && apply.status == 0
      apply.update_attributes(:status => 3)
      apply.tidings.destroy_all
      @shixun.update_column('status', 0)
    end
    redirect_to shixun_path(@shixun)
  end

  def close
    render_403 unless User.current.admin?
    @shixun.update_attributes(:status => 3, :closer_id => User.current.id, :end_time => Time.now)
    redirect_to shixun_path(@shixun)
  end

  # copy_shixun:复制一个新的实训模块包括版本库
  # copy_myshixun自动创建系列game,game中只包含状态等信息,公共信息从Challeges中读取
  # 开启过实训的则直接跳入my实训页面
  def shixun_exec
    # unless allow_shixun_exec(@shixun) && (User.current.manager_of_shixun?(@shixun) || @shixun.status > 0)
    #   render_403
    #   return
    # end
    # 添加事务锁,防止并发情况下tpi被多次创建
    myshixun = Myshixun.where(:user_id => User.current.id, :shixun_id => @shixun.id).first
    unless myshixun.blank?
      logger.info("current task id is #{myshixun.current_task}")

      redirect_to "/tasks/#{myshixun.current_task.identifier}"
      # redirect_to myshixun_game_path(myshixun.current_task, :myshixun_id => myshixun, :is_subject => params[:is_subject])
      return
    end
    ActiveRecord::Base.transaction do
      begin
        # fork版本库,如果用户没有同步,则先同步用户
        g = Gitlab.client
        if User.current.gid.nil?
          s = Trustie::Gitlab::Sync.new
          s.sync_user(User.current)
        end
        gshixun = g.fork(@shixun.gpid, User.current.gid)

        shixun_tomcat = Redmine::Configuration['shixun_tomcat']
        code = down_generate_identifier("myshixun")


        # 一般通过默认分支是否存在来判断一个项目是否fork成功
        if gshixun.try(:id).present?
          commit_id = g.commits(@shixun.gpid).first.try(:id)
          # educoder 加入到myshixun中
          myshixun_admin_gid = User.where(:login => "educoder").first.try(:gid)
          g.add_team_member(gshixun.id, myshixun_admin_gid, 40)  # 40代表角色master

          myshixun = Myshixun.create!(:shixun_id => @shixun.id, :user_id => User.current.id, :identifier => code, :modify_time => @shixun.modify_time,
                                      :reset_time => @shixun.reset_time, :onclick_time => Time.now, :gpid => gshixun.id,
                                      :git_url => gshixun.try(:path_with_namespace), :commit_id => commit_id)

          # tpm 不需要目录的
          # rep = Repository.create!(:myshixun_id => myshixun.id, :identifier => gshixun.name,:project_id => -1, :shixun_id => -2)
          # rep.update_column(:type, "Repository::Gitlab")
          rep_url = Base64.urlsafe_encode64(gitlab_url @shixun) # 注意:educoder为默认给实训创建版本库的用户,如果换成别的用户,名字要相应的修改

          logger.info("start openGameInstance")
          uri = "#{shixun_tomcat}/bridge/game/openGameInstance"
          logger.info("end openGameInstance")
          params = {tpiID: "#{myshixun.id}", tpmGitURL:rep_url, tpiRepoName: gshixun.try(:name)}
          logger.info("openGameInstance params is #{params}")
          res = uri_exec uri, params
          if (res && res['code'].to_i != 0)
            raise("实训云平台繁忙(繁忙等级:83)")
          end

          # 其它创建关卡等操作
          challenges = @shixun.challenges
          # 之所以增加user_id是为了方便统计查询性能
          challenges.each_with_index do |challenge, index|
            status = (index == 0 ? 0 : 3)
            code = down_generate_identifier("game")
            Game.create!(:challenge_id => challenge.id, :myshixun_id => myshixun.id, :status => status, :user_id => myshixun.user_id,
                         :open_time => Time.now, :identifier => code, :modify_time => challenge.modify_time)
            # 记录刚开始时默认代开文件原始代码
            # 刚开始fork的一段时间是获取不了content内容的
            # if challenge.st == 0 && challenge.path.present?
            #   paths = challenge.path.split(";")
            #   paths.each do |path|
            #     game_code_init(game.id, path)
            #   end
            # end
          end
          if params[:type] == "1"  # 重置过来的请求
            shixun_mod = ShixunModify.where(:shixun_id => myshixun.try(:shixun_id), :myshixun_id => myshixun.try(:id)).first
            if shixun_mod.nil?
              ShixunModify.create(:shixun_id => myshixun.shixun_id, :myshixun_id => myshixun.id, :status => 0)
            else
              shixun_mod.update_attributes(:status => 0)
            end
          end
        else
          raise("实训云平台繁忙(繁忙等级:81)")
        end
        # unlock
        logger.info("myshixun id is #{myshixun.try(:identifier)} and current_task id is#{myshixun.try(:current_task).try(:id)}")
        # 开启实训时更新关联作品的状态
        update_myshixun_work_status myshixun
        redirect_to myshixun_game_path(myshixun.current_task, :myshixun_id => myshixun, :is_subject => params[:is_subject])
      rescue Exception => e
        if e.message == "shixun error"
          flash[:error] = "正在后台执行,请稍后重试"
        elsif e.message.include?("Mysql2::Error")
          flash[:error] = "正在后台执行,请稍后重试"
        else
          flash[:error] = e.message
        end
        logger.error("###failed to exec shixun: current task id is #{e}")
        g.delete_project(gshixun.id) if gshixun.try(:id).present?
        redirect_to shixun_challenges_path(@shixun)
        raise ActiveRecord::Rollback
      end
    end
  end

  def shixun_courses
    data = {result:0,options:[]}
    if params[:major_id] != 0
      major = Major.find params[:major_id]
      if major
        data[:result] = 1
        major_courses = major.major_courses
        CourseList.where(:id => major_courses.map(&:course_list_id)).each do |course|
          option = []
          option << course.name.to_s
          option << course.id
          data[:options] << option
        end
      else
        data[:result] = 0
      end
    else
      data[:result] = 0
    end
    render :json =>data
  end

  def new
    @shixun = Shixun.new
    @support = Major.where(:support_shixuns=> 1)
    @introduction_sample =  PlatformSample.where(:samples_type => 'introduction').first.try(:contents)
    @knowledge_sample =  PlatformSample.where(:samples_type => 'knowledge').first.try(:contents)
    @main_type = MirrorRepository.published_main_mirror
    @small_type = MirrorRepository.published_small_mirror


    respond_to do |format|
      format.html{render :layout => 'base_edu'}
      format.json
    end
  end

  def departments
    respond_to do |format|
      format.js
    end
  end

  def create
    identifier = generate_identifier
    @shixun = Shixun.new(params[:shixun])
    @shixun.user_id = User.current.id
    @shixun.trainee = params[:trainee]
    @shixun.webssh = params[:webssh].to_i
    @shixun.multi_webssh = @shixun.webssh == 2 && params[:multi_webssh] == "1" ? 1 : 0
    @shixun.vnc = params[:vnc].to_i
    @shixun.can_copy = params[:can_copy].to_i
    @shixun.identifier = identifier
    @shixun.reset_time = Time.now
    @shixun.modify_time = Time.now
    @shixun.use_scope = params[:public_degree].to_i
    @shixun.visits = 1
    main_type = params[:main_type]
    sub_type = params[:small_type]

    mirror =  MirrorScript.where(:mirror_repository_id => main_type)
    if sub_type.blank?
      shixun_script = mirror.first.try(:script)
    else
      main_mirror = MirrorRepository.find(main_type).type_name
      sub_mirror = MirrorRepository.find(sub_type).type_name
      if main_mirror == "Java" && sub_mirror == "Mysql"
        shixun_script = mirror.last.try(:script)
      else
        shixun_script = mirror.first.try(:script)
        shixun_script = modify_shixun_script @shixun, shixun_script
      end
    end
    @shixun.evaluate_script = shixun_script

    ActiveRecord::Base.transaction do
      begin
        @shixun.save!
        if params[:scope_partment].present?
          arr = []
          ids = School.where(:name => params[:scope_partment]).map(&:id).uniq
          ids.each do |id|
            arr << { :school_id => id, :shixun_id => @shixun.id }
          end
          ShixunSchool.create!(arr)
        end
        m = ShixunMember.new(:user_id => User.current.id, :role => 1)
        @shixun.shixun_members << m
        # 镜像-实训关联表
        ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => main_type.to_i) if main_type.present?
        # 创建Pod配置信息
        ShixunServiceConfig.create!(:shixun_id => @shixun.id, :mirror_repository_id =>  main_type.to_i)
        if sub_type.present?
          sub_mirrors = sub_type.split(",").map(&:to_i)
          sub_mirrors.each do |mirror|
            ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror)
            ShixunServiceConfig.create!(:shixun_id => @shixun.id, :mirror_repository_id =>  mirror)
          end
        end
        #自动构建版本库
        repository = Repository.new
        repository.shixun = @shixun
        repository.type = 'Repository::Gitlab'
        repository.identifier = @shixun.identifier.downcase
        repository.project_id = -1
        repository.save!
        s = Trustie::Gitlab::Sync.new
        gproject = s.create_shixun(@shixun, repository)
        raise "版本库创建失败" if @shixun.gpid.blank?   # 若和gitlab没同步成功,则抛出异常
        g = Gitlab.client
        @shixun.update_column(:git_url, g.project(@shixun.gpid).path_with_namespace)
        # g = Gitlab.client
        # hook_url = Setting.protocol + "://" + Setting.host_name + "/shixuns/#{@shixun.identifier}" + "/ghook"
        # g.add_project_hook(@shixun.gpid, hook_url)
        redirect_to shixun_path @shixun, notice: l(:notice_successful_create)
      rescue Exception => e
        respond_to do |format|
          flash[:notice] = "#{e.message}"
          redirect_to new_shixun_path
          raise ActiveRecord::Rollback
        end
      end
    end
  end

  def copy
    # 实训设置了能复制并且(平台认证的老师或者实训管理员二选一)
    unless (@shixun.can_copy && ((User.current.user_extensions.try(:identity) == 0 && User.current.professional_certification) || User.current.manager_of_shixun?(@shixun)))
      render_403
      return
    end
    ActiveRecord::Base.transaction do
      begin
        raise "请先绑定邮箱"  if User.current.mail.blank?
        new_shixun = Shixun.new
        new_shixun.attributes = @shixun.attributes.dup.except("id","user_id","visits","gpid","status", "identifier", "homepage_show","git_url", "propaedeutics")
        new_shixun.user_id = User.current.id
        new_shixun.identifier = generate_identifier
        new_shixun.status = 0
        new_shixun.visits = 1
        new_shixun.fork_from = @shixun.id
        new_shixun.save!
        shixun_major_courses = ShixunMajorCourse.where(:shixun_id => @shixun.id)
        if shixun_major_courses.present?
          shixun_major_courses.each do |smc|
            ShixunMajorCourse.create!(:shixun_id => new_shixun.id, :major_id => smc.major_id, :course_list_id => smc.course_list_id)
          end
        end
        # 同步镜像
        if @shixun.mirror_repositories.present?
          @shixun.mirror_repositories.each do |mirror|
            ShixunMirrorRepository.create!(:shixun_id => new_shixun.id, :mirror_repository_id => mirror.id)
          end
        end
        # 同步技术标签
        @shixun.shixun_tag_repertoires.each do |str|
          ShixunTagRepertoire.create!(:tag_repertoire_id => str.tag_repertoire_id, :shixun_id => new_shixun.id)
        end

        # 同步配置
        @shixun.shixun_service_configs.each do |config|
          ShixunServiceConfig.create!(:shixun_id => new_shixun.id,
                                      :cpu_limit => config.cpu_limit,
                                      :lower_cpu_limit => config.lower_cpu_limit,
                                      :memory_limit => config.memory_limit,
                                      :request_limit => config.request_limit,
                                      :mirror_repository_id => config.mirror_repository_id)
        end

        # 同步复制版本库,先fork再修改版本库名
        # eduforge用户作为版本库的创建者
        repository = Repository.new
        repository.shixun = new_shixun
        repository.type = 'Repository::Gitlab'
        repository.identifier = new_shixun.identifier.downcase
        repository.project_id = -1
        repository.save!
        g = Gitlab.client
        user_gid = User.find_by_mail("eduforge@163.com").try(:gid)
        gshixun = g.fork(@shixun.gpid, user_gid)
        raise "版本库创建失败" if gshixun.try(:id).blank?

        # gshixun = g.edit_project(gshixun.id, new_shixun.identifier, new_shixun.identifier)
        # raise "实训复制失败" if (gshixun.try(:name) != new_shixun.identifier || gshixun.try(:path) != new_shixun.identifier)
        new_shixun.update_attributes!(:gpid => gshixun.id, :git_url => gshixun.try(:path_with_namespace))
        # 同步复制者至gitlab, 必须要求用户绑定了邮箱
        ShixunMember.create!(:user_id => User.current.id, :shixun_id => new_shixun.try(:id), :role => 1)

        gid = User.current.try(:gid)
        if gid.nil?
          s = Trustie::Gitlab::Sync.new
          gid = s.sync_user(User.current).try(:id)
        end
        g.add_team_member(gshixun.id, gid, 40)  # 3代表角色master

        # # 同步复制合作者,合作者加入到gitlab
        # unless User.current.manager_of_shixun?(@shixun)
        #   ShixunMember.create!(:user_id => User.current.id, :shixun_id => new_shixun.try(:id), :role => 1)
        # end
        # @shixun.shixun_members.each do |shixun_member|
        #   if ShixunMember.where(:shixun_id => new_shixun.try(:id), :user_id => shixun_member.user_id).blank?
        #     ShixunMember.create!(:user_id => shixun_member.try(:user_id), :shixun_id => new_shixun.try(:id),
        #                           :role => (shixun_member.try(:user_id) == User.current.id ? 1 : 2))
        #   end
        #   s = Trustie::Gitlab::Sync.new
        #   gid = User.find(shixun_member.user_id).try(:gid)
        #   u = s.g.add_team_member(gshixun.id, gid, 40)  # 3代表角色master
        #   if u.blank?
        #     raise("同步Gitlab数据失败")
        #   end
        # end
        # 同步复制关卡
        if @shixun.challenges.present?
          @shixun.challenges.each do |challenge|
            new_challenge = Challenge.new
            new_challenge.attributes = challenge.attributes.dup.except("id","shixun_id","user_id")
            new_challenge.user_id = User.current.id
            new_challenge.shixun_id = new_shixun.id
            new_challenge.save!
            if challenge.st == 0  # 评测题
              # 同步测试集
              if challenge.test_sets.present?
                challenge.test_sets.each do |test_set|
                  new_test_set = TestSet.new
                  new_test_set.attributes = test_set.attributes.dup.except("id","challenge_id")
                  new_test_set.challenge_id = new_challenge.id
                  new_test_set.save!
                end
              end
              # 同步关卡标签
              challenge_tags = ChallengeTag.where("challenge_id =? and challenge_choose_id is null", challenge.id)
              if challenge_tags.present?
                challenge_tags.each do |challenge_tag|
                  ChallengeTag.create!(:challenge_id => new_challenge.id, :name => challenge_tag.try(:name))
                end
              end
            elsif challenge.st == 1  # 选择题
              if challenge.challenge_chooses.present?
                challenge.challenge_chooses.each do |challenge_choose|
                  new_challenge_choose = ChallengeChoose.new
                  new_challenge_choose.attributes = challenge_choose.attributes.dup.except("id","challenge_id")
                  new_challenge_choose.challenge_id = new_challenge.id
                  new_challenge_choose.save!
                  # 每一题的选项
                  if challenge_choose.challenge_questions.present?
                    challenge_choose.challenge_questions.each do |challenge_question|
                      new_challenge_question = ChallengeQuestion.new
                      new_challenge_question.attributes = challenge_question.attributes.dup.except("id","challenge_choose_id")
                      new_challenge_question.challenge_choose_id = new_challenge_choose.id
                      new_challenge_question.save!
                    end
                  end
                  # 每一题的知识标签
                  st_challenge_tags = ChallengeTag.where(:challenge_id => challenge.id, :challenge_choose_id => challenge_choose.id)
                  if st_challenge_tags.present?
                    st_challenge_tags.each do |st_challenge_tag|
                      ChallengeTag.create!(:challenge_id => new_challenge.id, :name => st_challenge_tag.try(:name), :challenge_choose_id => new_challenge_choose.id)
                    end
                  end
                end
              end
            end
          end
        end
        # 中间层创建测试集
        #shixun_modify_status_publish(new_shixun, 1)
        flash[:notice] = "实训复制成功"
        redirect_to shixun_challenges_path(new_shixun)
      rescue Exception => e
        logger.info("copy shixun failed ##{e.message}")
        flash[:notice] = "#{e.message}"
        g.delete_project(gshixun.id) if gshixun.try(:id).present?  # 异常后,如果已经创建了版本库需要删除该版本库
        redirect_to shixun_challenges_path(@shixun)
        raise ActiveRecord::Rollback
      end
    end
  end

  def fork_list
    @shixuns = Shixun.where(:fork_from => @shixun.id)
    @shixuns_count = @shixuns.count
    @limit = 16
    @is_remote = true
    @shixun_pages = Paginator.new @shixuns_count, @limit, params['page'] || 1
    @offset ||= @shixun_pages.offset
    @shixuns = paginateHelper @shixuns, @limit
  end

  def show
    # 如果是从TPI中退出,则更新TPI时间
    # 更新时间是为了TPM端显示的更新,退出实训及访问实训的时候会更新
    if params[:exit] && !User.current.admin?
      @shixun.myshixuns.where(:user_id => User.current).first.update_column(:updated_at, Time.now)
    end
    respond_to do |format|
      format.html{redirect_to shixun_challenges_path(@shixun)}
    end
  end

  def generate_identifier
    code = DCODES.sample(8).join
    return generate_identifier if Shixun.where(identifier: code).present?
    code
  end

  def down_generate_identifier type
    if type == "game"
      code = DCODES.sample(12).join
      return down_generate_identifier(type) if Game.where(identifier: code).present?
    elsif type == "myshixun"
      code = DCODES.sample(10).join
      return down_generate_identifier(type) if Myshixun.where(identifier: code).present?
    end
    code
  end

  def edit
  end

  def update
    logger.info("#######-----#{params[:config]}")
    @shixun.attributes = params[:shixun]
    #@shixun.language = params[:language]
    @shixun.trainee = params[:trainee]
    @shixun.webssh = params[:webssh].to_i
    @shixun.multi_webssh = @shixun.webssh == 2 && params[:multi_webssh] == "1" ? 1 : 0
    @shixun.vnc = params[:vnc].to_i
    @shixun.can_copy = params[:can_copy].to_i
    @shixun.test_set_permission = params[:test_set_permission].to_i
    @shixun.code_hidden = params[:code_hidden].to_i
    @shixun.task_pass = params[:task_pass].to_i
    @shixun.mirror_script_id = params[:mirror_script].to_i
    @shixun.hide_code = params[:hide_code].to_i
    @shixun.forbid_copy = params[:forbid_copy].to_i
    if params[:public_degree]
      use_scope = params[:public_degree].to_i
    else
      use_scope = @shixun.use_scope
    end
    mirror_ids = (@shixun.shixun_mirror_repositories.blank? ? [] : @shixun.shixun_mirror_repositories.map(&:id))
    update_miiror_id = []
    @shixun.shixun_mirror_repositories.destroy_all

    if params[:main_type].present?
      update_miiror_id << params[:main_type].to_i
      ShixunMirrorRepository.create(:shixun_id => @shixun.id, :mirror_repository_id => params[:main_type])
    end
    if params[:small_type].present?
      sub_mirrors = params[:small_type].split(",").map(&:to_i)
      sub_mirrors.each do |mirror|
        update_miiror_id << mirror
        ShixunMirrorRepository.create(:shixun_id => @shixun.id, :mirror_repository_id => mirror)
      end
    end
    # 超级管理员才能保存 中间层服务器pod信息的配置
    @shixun.shixun_service_configs.destroy_all
    params[:mirror_id].each_with_index do |mirror_id, index|
      ShixunServiceConfig.create!(:shixun_id => @shixun.id,
                                  :cpu_limit => params[:cpu_limit][index],
                                  :lower_cpu_limit => params[:lower_cpu_limit][index],
                                  :memory_limit => params[:memory_limit][index],
                                  # :resource_limit => params[:resource_limit][index],
                                  :request_limit => params[:request_limit][index],
                                  :mirror_repository_id => mirror_id)
    end

    ActiveRecord::Base.transaction do
      begin
        @shixun.save!
        @shixun.shixun_schools.delete_all
        if params[:scope_partment].present? && use_scope == 1
          arr = []
          @shixun.schools
          ids = School.where(:name => params[:scope_partment]).map(&:id).uniq
          ids.each do |id|
            arr << { :school_id => id, :shixun_id => @shixun.id }
          end
          ShixunSchool.create!(arr)
        else
          use_scope = 0
        end
        @shixun.update_attributes!(:use_scope => use_scope)
      rescue
        @error = "实训保存失败"
        raise ActiveRecord::Rollback
      end
    end
    respond_to do |format|
      format.js
      format.html{redirect_to settings_shixun_path(@shixun)}
    end
  end

  def shixun_discuss
    if User.current.logged?
      render file: 'public/react/build/index.html', :layout => false
    else
      redirect_to signin_path
    end

    # @discusses = @shixun.discusses.reorder("created_at desc")
    # @discusses_num = @discusses.count
    # @discusses = get_no_children_comments_all @discusses
    # @discusses_count = @discusses.count
    # @limit = 15
    # @is_remote = true
    # @discusses_pages = Paginator.new @discusses_count, @limit, params['page'] || 1
    # @offset ||= @discusses_pages.offset
    # @discusses = paginateHelper @discusses, @limit
    # #@game_challenge = params[:challenge_id].blank? ? Challenge.find(@discusses.first.try(:challenge_id)) : Challenge.find(params[:challenge_id])
    # challenge_id =  params[:challenge_id].nil? ? @shixun.challenges.first.try(:id) : params[:challenge_id].to_i
    # @game_challenge = Challenge.find(challenge_id)
    # @praise = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and praise_or_tread=? and user_id=?", @game_challenge.id, @game_challenge.class.to_s, 1, User.current.id).first
    # @tread = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and praise_or_tread=? and user_id=?", @game_challenge.id, @game_challenge.class.to_s, 0, User.current.id).first
    # @praise_count = PraiseTread.where(:praise_tread_object_id => @game_challenge.id, :praise_tread_object_type => "Challenge", :praise_or_tread => 1).count
    # @tread_count  = PraiseTread.where(:praise_tread_object_id => @game_challenge.id, :praise_tread_object_type => "Challenge", :praise_or_tread => 0).count
    #
    # respond_to do |format|
    #   format.js
    #   format.html
    # end
  end

  def destroy
    render_403 if @shixun.status > 1 && !User.current.admin?
    ActiveRecord::Base.transaction do
      g = Gitlab.client
      g.delete_project(@shixun.gpid) if @shixun.try(:gpid).present?
      apply_record = ApplyAction.where(:container_id => @shixun.id, :container_type => "ApplyShixun")
      apply_record.delete_all if apply_record
      #HomeworkCommonsShixuns.where(:shixun_id => @shixun).delete_all # 关联删报错,后续解决
      @shixun.update_attribute(:status, -1)
      respond_to do |format|
        if params[:come_from] == "admin"
          format.html{ redirect_to shixuns_managements_path }
        else
          format.html{ redirect_to user_path(User.current) }
        end
        format.js
      end
    end
  end

  def settings
    @edit = params[:edit]
    @repository = Repository.where(:shixun_id => @shixun, :type => "Repository::Gitlab").first
    @main_type = MirrorRepository.published_main_mirror
    @small_type = MirrorRepository.published_small_mirror
    @shixun_main_mirror = @shixun.mirror_repositories.published_main_mirror.first
    # 权限
    logger.info("###########{User.current.admin?}")
    logger.info("#########business:##{User.current.business?}")
    @power = (@shixun.status < 2 ? true : ( User.current.admin? ? true : false))
    # unless @repository.nil?
    #   gitlab_address = Redmine::Configuration['gitlab_address']
    #   login = User.find_by_mail("educoder@163.com").try(:login)
    #   @repos_url = gitlab_url @shixun
    # end
    respond_to do |format|
      format.html
      format.js
    end
  end

  # 添加实训脚本
  def add_script
    if @shixun.update_attribute(:script, params[:shixun_script])
      @notice = "脚本添加成功"
    else
      @notice = "脚本添加失败"
    end
  end

  def get_mirror_script
    mirror = MirrorRepository.find(params[:mirror_id])
    script = mirror.mirror_scripts if mirror
    render :json => script
  end

  def get_script_contents
    if params[:script_id].to_i == -1
      render :json => {contents: "", description: ""}
    else
      mirrir_script =  MirrorScript.find(params[:script_id])
      script = mirrir_script.try(:script)
      description = mirrir_script.try(:description)
      script = modify_shixun_script @shixun, script
      render :json => {contents: script, description: description}
    end

  end

  def get_common_script
    shixun_script = PlatformSample.where(:samples_type => "script").first.try(:contents)
    compile = params[:compile]
    execute = params[:executive]
    if shixun_script
      shixun_script = compile.blank? ? shixun_script.gsub("COMPILEFUNCTION", "").gsub("CHALLENGEFIELPATH", "") : shixun_script.gsub("COMPILEFUNCTION", "#{compile_command}").gsub("COMPILECOMMAND", "#{compile}")
      shixun_script = execute.blank? ? shixun_script.gsub("EXECUTEFUNCTION", "") : shixun_script.gsub("EXECUTECOMMAND", "#{execute}")
      shixun_script = modify_shixun_script @shixun, shixun_script
    end
    render :json => {contents: shixun_script}
  end

  # 创建实训job
  def shixun_job_create
    if @shixun.challenges.count == 0
      @notice = "实训开启失败:请先发布实训任务"
      return
    elsif Repository.where(:shixun_id => @shixun.id, :type => "Repository::Gitlab").count == 0
      @notice = "实训开启失败:请先创建版本库"
      return
    end
    @shixun.update_attribute(:status, 1)
  end

  # 更新实训job
  def shixun_job_update
    # jobName = "#{@shixun.id}"
    # pipeLine = "#{Base64.encode64(@shixun.script)}"
    # uri = URI("http://123.59.135.74:9999/jenkins-exec/api/updateJob")
    # params = {jobName: jobName, pipeLine: pipeLine}
    # res = uri_exec uri, params
    training_shixun_notice res
    if res['code'] == 0
      @shixun.update_attribute(:status, 1)
    end
  end

  # Find shixun of id params[:id]
  def find_shixun
    @shixun = Shixun.find_by_identifier(params[:id])
    render_404 if @shixun.nil? || @shixun.status == -1
  rescue ActiveRecord::RecordNotFound
    render_404
  end

  def monitor_filter
    if User.current.id == @shixun.user_id
      @notice = l(:label_shixun_mine)
    else
      if has_exec_cur_shixun(@shixun)
        @notice = l(:label_shixun_had_forked)
        @had_exec = true
      else
        @notice = l(:label_shixun_exec)
        @had_exec = false
      end
    end
  end

  # 实训行为操作
  def operation
    @is_subject = params[:is_subject]
    @myshixun = Myshixun.where(:id => params[:myshixun_id]).first
    @is_modify = ShixunModify.where(:myshixun_id => params[:myshixun_id], :shixun_id => @shixun.try(:id), :status => 1).first
    @mail = User.current.mail.blank?
    # @challenge_count = @shixun.challenges.count
    # @git_commit = Gitlab.client.trees(@shixun.gpid).count.to_i

    @choice_shixun = @shixun.is_choice_type
    unfinish_challenge = @shixun.challenges.where(:path => nil, :st => 0) # 学员任务文件是否为空
    if unfinish_challenge.count > 0 && !@shixun.is_choice_type
      @pos = []
      unfinish_challenge.each do |challenge|
        @pos << challenge.position
      end
      @pos = @pos.join(",")
    end
  end

  # 实训的发送至课堂:搜索课堂
  def search_user_courses
    @user = User.current
    if !params[:search].nil?
      search = "%#{params[:search].to_s.strip.downcase}%"
      @courses = @user.courses.not_deleted_not_end.where("#{Course.table_name}.name like :p",:p=>search).select{|course| @user.has_teacher_role(course)}
    else
      @courses = @user.courses.not_deleted_not_end.select{|course| @user.has_teacher_role(course)}
    end
    @pages = Paginator.new @courses.count, 8, params['page'] || 1
    @offset ||= @pages.offset
    @courses = paginateHelper @courses, 8
    respond_to do |format|
      format.js
    end
  end

  # 将实训发送到课程
  def send_to_course
    course = Course.where(:id => params[:course]).first
    if course.present?
      homework = HomeworkCommon.new
      homework.name = @shixun.name
      homework.description = @shixun.description
      homework.anonymous_comment = 1
      homework.homework_type = 4
      homework.late_penalty = 0
      homework.teacher_priority = 1
      homework.user_id = User.current.id
      homework.course_id = params[:course]

      homework_detail_manual = HomeworkDetailManual.new
      homework_detail_manual.te_proportion = 1.0
      homework_detail_manual.ta_proportion = 0
      homework_detail_manual.comment_status = 0

      homework_detail_manual.evaluation_num = 0
      homework_detail_manual.absence_penalty = 0
      homework.homework_detail_manual = homework_detail_manual
      if homework.save!
        homework_detail_manual.save if homework_detail_manual
        HomeworkCommonsShixuns.create(:homework_common_id => homework.id, :shixun_id => @shixun.id)
        create_shixun_homework_cha_setting homework, @shixun
        create_works_list homework
        redirect_to homework_common_index_path(:course => course.id, :homework_type => 4)
      end
    else
      render_404
    end
  end
  private
  def view_allow
    shixun_view_allow @shixun
  end

  # REDO: 新增类型copy的时候
  # 复制项目
  # gshixun --> gitlab project
  # CODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
  def copy_myshixun shixun, gshixun
    myshixun = Myshixun.new
    # myshixun.attributes = shixun.attributes.dup.except("id","user_id","visits","gpid","status", "identifier","propaedeutics")
    myshixun.shixun_id = shixun.id
    myshixun.user_id = User.current.id
    myshixun.gpid = gshixun.id
    shixun_tomcat = Redmine::Configuration['shixun_tomcat']
    if myshixun.save!
      # 为了避免fork多次的问题
      if gshixun.try(:name).include?("-")
        logger.info("***** gshixun name is #{gshixun.try(:name)}")
        @g.delete_project(gshixun.id)
        gshixun = @g.project(myshixun.gpid)
        myshixun.update_column(:gpid, gshixun.id)
      end
      code = down_generate_identifier("myshixun")
      myshixun.update_attribute(:identifier, code)
      rep = Repository.new(:myshixun_id => myshixun.id, :identifier => gshixun.name,:project_id => -1, :shixun_id => -2)
      rep.type = "Repository::Gitlab"
      rep.save!
      login = User.find_by_mail("educoder@163.com").try(:login)
      rep_url = Base64.urlsafe_encode64(gitlab_url shixun)
      uri = "#{shixun_tomcat}/bridge/game/openGameInstance"
      params = {tpiID: "#{myshixun.id}", tpmID: "#{shixun.id}", instanceGitURL:rep_url, operationEnvironment:"#{shixun.try(:language)}"}
      logger.info("openGameInstance params is #{params}")
      res = uri_exec uri, params
      if (res && res['code'].to_i != 0)
        raise("实训云平台繁忙(繁忙等级:83)")
      end
      return myshixun
    end
  end

  def training_shixun_notice res
    if res['code'] == 0
      @notice = "实训开启成功"
    else
      @notice = res['msg'].nil? ? "实训开启失败" : res['msg']
    end
  end

  # 实训管理员或者超级管理员
  def require_manager
    render_403 unless User.current.manager_of_shixun?(@shixun)
  end

  def validation_email
    render_403 if User.current.mail.blank?
  end

  def validate_shixun

  end
end