Buildwise::App.controllers :test_files do
  
  get "/:id/history" do
    @test_file = TestFile.find_by_id(params[:id])
    if @test_file
      @test_file_name = @test_file.filename

      @the_build = @test_file.build 
      @project = @the_build.project
      max_test_file_history = settings.max_test_file_history
      if max_test_file_history.nil? || max_test_file_history.to_i == 0
        max_test_file_history = 10
      end
      
      past_test_file_runs = TestFile.joins(:build).where(:filename => @test_file_name).where("builds.id <= ? and builds.project_id = ?", @test_file.build.id, @project.id)
      


      begin
        @test_runs = past_test_file_runs.order("TEST_FILES.ID DESC").limit(max_test_file_history)
        @test_runs.count # this is to verfy ORDER error
      rescue => e

        @test_runs = past_test_file_runs.order("ID DESC").limit(max_test_file_history)
      end
    
      @recent_build_times = []

      @test_runs.each do |tr|
        next if tr.duration.nil?    
        begin

          the_duration = tr.duration.round( @the_build.test_syntax_framework == "JUnit" ? 3 : 1)
        rescue => e
          next # not valid entry in
        end
        
        the_color = '#8bbc21'
        if !tr.successful
          the_color = '#d9534f'
        elsif tr.build == @test_file.build
          the_color = '#2f7ed8'
        end
        @recent_build_times << {time: tr.build.start_time, duration: the_duration, :successful => tr.successful, color: the_color, agent: tr.agent }        
      end

      @recent_build_times.sort! { |a, b| a[:time] <=> b[:time] }
    end
    render "/test_files/history".to_sym, :layout => false
  end



  get "/:id/rerun", :provides => [:js]  do
    authenticate_admin!
    @test_file = TestFile.find_by_id(params[:id])
    @test_file.status = nil
    @test_file.past_agents = @test_file.agent
    @test_file.agent = nil
    @test_file.result = nil
    @test_file.save
    render "/test_files/rerun.js".to_sym, :layout => false    
  end

  get "/:id" do
    @test_file = TestFile.find_by_id(params[:id])
    @scripts = highlight_test_file(@test_file)
    return @scripts
  end

  get "/:id/update_priority", :provides => [:js] do
    authenticate_admin!
    
    @test_file = TestFile.find_by_id(params[:id])
    @priority = params[:priority].to_i
    @test_file.update_column(:priority, @priority)
    render "/test_files/update_priority.js".to_sym, :layout => false
  end


  get "/:id/execute", :provides => [:js] do
    authenticate_admin!
    @test_file = TestFile.find_by_id(params[:id])
    @project = @test_file.build.project

    test_file_path = get_test_file_path_on_server(@project, @test_file.filename)
    @error = nil
    if !File.exist?(test_file_path)
      @error = "File #{test_file_path} not exists"
    else
      current_dir = File.expand_path(".")
      @test_output = nil
      start_time = Time.now
      

      env_vars = { "BUILDWISE_MASTER" => root_url }
      if @project && @project.config
        @project.config.environment_variables.each do |key, val|
          env_vars[key] = val
        end 
      end
      
      puts "\n\n [DEBUG] execute with env_vars: #{env_vars.inspect}\n\n"
      
      begin        
        @test_output = execute_test_script(test_file_path, env_vars)       
      rescue => e
        logger.warn("Failed to run test: #{e.message}")

      ensure        
        @execution_time = (Time.now - start_time).to_i;
        FileUtils.chdir(current_dir)
      end      
    end
    
    render "/test_files/execute.js".to_sym, :layout => false    
  end
  
  get "/execute_test/:id", :provides => [:js] do
    authenticate_admin!
    @test_case = TestCase.find_by_id(params[:id])
    @test_file = @test_case.test_file
    @project = @test_file.build.project

    test_file_path = get_test_file_path_on_server(@project, @test_file.filename)

    if (@project.config.ui_tests_local_working_dir && Dir.exist?(@project.config.ui_tests_local_working_dir) )
      test_file_path = File.join(@project.config.ui_tests_local_working_dir, @test_file.filename)
    end

    env_vars = { "BUILDWISE_MASTER" => root_url }
    if @project && @project.config
      @project.config.environment_variables.each do |key, val|
        env_vars[key] = val
      end 
    end
    
    @error = nil
    if !File.exist?(test_file_path)
      @error = "File #{test_file_path} not exists"
    else
      current_dir = File.expand_path(".")
      @test_output = nil
      start_time = Time.now
      begin
        test_case_name = @test_case.name.gsub("'", "\'")      
        @test_output = execute_individual_test_case(test_file_path, test_case_name, env_vars)
      rescue => e
        logger.warn("Failed to execute test case: #{test_file_path} #{test_case_name}, #{e}")
      ensure        
        @execution_time = (Time.now - start_time).to_i;
        FileUtils.chdir(current_dir)
      end      
    end

    render "/test_files/execute_test.js", :layout => false           
  end
  
  
  get "/prepare_test_execution/:id", :provides => :js do
    authenticate_admin!
    @test_case = TestCase.find_by_id(params[:id])
    @test_file = @test_case.test_file
    @project = @test_file.build.project
    
    test_file_path = File.join(@project.working_dir, "sources",  @project.config.ui_tests_dir, @test_file.filename)    
    spec_file = SpecFile.new(test_file_path)        
    @spec_behaviour = spec_file.behaviour_lookups[@test_case.name]
    
    @modal_content = partial("/test_files/custom_test_execution_modal").gsub("\n", "");
    render "/test_files/prepare_test_execution.js".to_sym, :layout => false
  end
  
  post "/execute_test_custom/:id", :provides =>  [:js] do
    authenticate_admin!
    
    @test_case = TestCase.find_by_id(params[:id])
    @test_file = @test_case.test_file
    @project = @test_file.build.project
    
    the_project_config_env_vars = @project.config.environment_variables


    request_ip = request.ip
    
    flag_kill_browser_on_custom_execution = the_project_config_env_vars["KILL_BROWSER_ON_CUSTOM_EXECUTION"].to_s == "true" rescue false 
    
    if flag_kill_browser_on_custom_execution && request_ip != "127.0.0.1"
      begin
        if RUBY_PLATFORM =~ /mingw/
          `taskkill /F /IM chromedriver.exe`
          `taskkill /F /IM chrome.exe`
        elsif RUBY_PLATFORM =~ /darwin/
          `pkill -f chromedriver`
          `pkill -f Chrome`
        else
          `killall -9 chromedriver`
          `killall -9 chrome`      
        end
      rescue => e
      end
    end
  
    env_vars = { "BUILDWISE_MASTER" => root_url }
    
    if @project && @project.config
      @project.config.environment_variables.each do |key, val|
        env_vars[key] = val
      end 
    end
    

    if params["env_var_key"] && params["env_var_key"].size > 0      
      key_hash = params["env_var_key"]
      value_hash = params["env_var_value"]      
      key_hash.each do |key_id, key|
        val = value_hash[key_id]
        if val && val.class == String
          val = val.strip 
        end
        next if val.class == String && val.blank?
        

        if val.class == Array && val.size == 1
          val = val.first.to_s
        end
        
        env_vars[key] = val


        if defined?(key) && key == "SERVER"
          session[:custom_execution_server] = (val.class == Array) ? val.first.to_s : val.to_s rescue nil
        end

      end 
      
    end
    
  
    test_file_path = get_test_file_path_on_server(@project, @test_file.filename)

    @error = nil
    if !File.exist?(test_file_path)
      @error = "File #{test_file_path} not exists"
    else
      current_dir = File.expand_path(".")
      @test_output = nil
      start_time = Time.now
      begin
        test_case_name = @test_case.name.gsub("'", "\'")      
        @test_output = execute_individual_test_case(test_file_path, test_case_name, env_vars)
      rescue => e
        logger.warn("Failed to execute test case: #{test_file_path} #{test_case_name}, #{e}")
      ensure        
        @execution_time = (Time.now - start_time).to_i;
        FileUtils.chdir(current_dir)
      end      
    end        
    
    render "/test_files/execute_test_custom.js", :layout => false
  end
  

end