
module Buildwise
	class App
		module ApplicationHelper
      
      
      def delete_cache_projects
        Buildwise::App.cache.clear
      end
      
      def cache_project_edit(a_project)
        if a_project && a_project.identifier
          cache_key "project_#{@project.identifier}_edit".to_sym
          expires 60
        end
      end
    
      def delete_cache_project_edit(a_project)
        if a_project && a_project.identifier
          Buildwise::App.cache.delete("project_#{@project.identifier}_edit".to_sym)        
        end
      end
      
      
      
      def raw(stringish)
        stringish.to_s.html_safe
      end

      def authenticate!
        unless session[:user_id]
          puts "request #{request.env["REQUEST_URI"]}" 
          session[:original_request] = request.env["REQUEST_URI"]
          redirect '/login'
        end
      end
      
      def authenticate_admin!
        authenticate!
        unless current_user.is_admin?

          redirect '/'    
        end
      end      
      
      def authenticate_admin_or_self!
        authenticate!
        the_current_user = current_user
        if the_current_user.is_admin? || @user == the_current_user
        else 

          flash[:error] = "Not allowed."
          redirect '/'    
        end
      end      
      
      def authenticate_admin_or_project_builder!(project)
        authenticate!
        the_current_user = current_user        
        if the_current_user.is_admin? || the_current_user.has_role?(:builder, project)
        else 

          flash[:error] = "Not allowed."
          redirect '/'    
        end
      end      

      def redirect_to_original_request
        @user = User.find_by_id(session[:user_id])

        original_request = session[:original_request]
        session[:original_request] = nil
        redirect original_request
      end  
      
      
      def determine_scm(path)
        scm = nil
        begin
          scm  = BuildWise::SCM.guess_type(path)
        rescue => e
          puts "Failed: to determine scm: #{e}"
        end
        return scm
      end


      def remember(a_user)
        a_user.remember
        cookies[:user_id] = a_user.id
        cookies[:remember_token] = a_user.remember_token
      end

      def escape_quotes(text)
        escaped = text.gsub("'", "&apos;").gsub('"', '&quot;')
        return escaped
      end

      def root_url
        request.url.match(/(^.*\/{2}[^\/]*)/)[1]
      end

      def format_time(time, format = :iso)
        TimeFormatter.new(time).send(format)
      end

      def format_seconds(total_seconds = 0, format = :general)
        DurationFormatter.new(total_seconds.to_i).send(format)
      end

      def display_build_time(date)

        format_time(date, :iso_this_year)
      end

      def display_builder_state(state)
        case state
          when 'building', 'builder_down', 'build_requested', 'source_control_error', 'queued', 'timed_out', 'error'
            "<div class=\"builder_status_#{state}\">#{state.gsub('_', ' ')}</div>"
          when 'sleeping', 'checking_for_modifications'
            ''
          else
            "<div class=\"builder_status_unknown\">#{h state}<br/>unknown state</div>"
        end
      end

      def file_icon_image(file_name)
        return "<img src='/images/document-text.png'/>" if file_name.nil?
        ext_name = File.extname(file_name) || ""
        if [".zip", ".war", ".ear"].include?(ext_name.downcase) then
          "<img src='/images/document-zipper.png'/>"
        elsif [".pdf"].include?(ext_name.downcase) then
          "<img src='/images/document-pdf.png'/>"
        else
          "<img src='/images/document-text.png'/>"
        end
      end

      def file_icon_fontawesome(file_name)
        return '<i class="fa fa-file-text" aria-hidden="true"></i>' if file_name.nil?
        ext_name = File.extname(file_name) || ""
        if [".zip", ".war", ".ear", ".gz", ".tar", ".7z"].include?(ext_name.downcase) then
          "<i class=\"fa fa-file-archive-o\" aria-hidden=\"true\"></i>"
        elsif [".pdf"].include?(ext_name.downcase) then
          "<i class=\"fa fa-file-pdf-o\" aria-hidden=\"true\"></i>"
        elsif [".csv", ".xls"].include?(ext_name.downcase) then
          "<i class=\"fa fa-file-excel-o\" aria-hidden=\"true\"></i>"
        else
          "<i class=\"fa fa-file-text-o\" aria-hidden=\"true\"></i>"
        end
      end

      def file_icon(file_name)
        file_icon_fontawesome(file_name)
      end
      
      def is_binary_file?(file_name)
        ext_name = File.extname(file_name) || ""
        [".zip", ".war", ".ear", ".pdf", ".xls", ".xlsx", ".tar", ".gz", ".7z", ".rar"].include?(ext_name.downcase)
      end

      def folder_html_icon
        "<img src='/images/folder-open-table.png'/>"
      end

      def format_comma_number(num)
        num.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
      end




      def scm_image(project)
        return "" unless project && project.source_control
        if project.source_control == "subversion" || project.source_control == "svn"
          return "<img src='/images/scm_subversion.png' width='16' height='16'/>"
        elsif project.source_control == "git"
          return '<i class="fa fa-git" aria-hidden="true"></i>'
        end
      end

      def browser_image(browser)
        return "" unless browser
        return "<img src='/images/buildwise/browser_#{browser.downcase}.png' width='16' height='16'/>"
      end

      def build_poll_image(project)
        if project && project.config(false) 
          poll_enabled = project.config(false).scheduler_polling rescue false
          poll_enabled && poll_enabled != "false" ? "<img src='/images/clock-history-frame.png'/>" : ""
        end
      end

      def build_timed_image(project)
        if project && project.config(false) 

          timed_enabled = project.config(false).scheduler_at_time rescue false
          timed_enabled && timed_enabled != "false" ? "<img src='/images/clock-select.png'/>" : ""
        end
      end

      def func_test_image(project)
        if project && project.ui_tests
          return "<img src='/images/application-browser.png'/>"
        end
      end

      def grid_func_test_image(project)
        if project && project.config && project.config.is_parallel
          return "<span data-toggle='tooltip' data-placement='left' title='" + I18n.t(:parallel_test_execution_tooltip) + "'><i class='fa fa-arrows-alt' aria-hidden='true'></i></span>"
        else
          return ""
        end
      end

      def ui_test_image(project)
        if project && project.config && project.config.builder_ui_test_task_enabled 
          return "<span data-toggle='tooltip' data-placement='left' title='" + I18n.t(:ui_test_tooltip) + "'><i class='fa fa-chrome' aria-hidden='true'></i></span>"

        else
          return ""
        end
      end

      def build_list_label(build)
        text = " " + "[" + build.label + "]" rescue build.label








      end

      def format_build_log(log)
        begin
          strip_ansi_colors(highlight_sections(highlight_test_count(link_to_code(h(log)))))
        rescue => e

          "<hr><p>Error on displaying the build log: #{e}</p></hr>" + log
        end
      end

      def link_to_code(log)
        return log
      end

      def highlight_sections(log)
        log.gsub(/###(.+)###/, '<div class="build-section">\1</div>')
      end

      def highlight_test_count(log)
        log.gsub(/\d+ tests, \d+ assertions, \d+ failures, \d+ errors/, '<div class="test-results">\0</div>').
            gsub(/\d+ examples, \d+ failures/, '<div class="test-results">\0</div>')
      end

      def strip_ansi_colors(log)
        log.gsub(/\e\[\d+m/, '')
      end

      def highlight_test_scripts(file)
        require 'coderay'
        tokens = CodeRay.scan(File.read(file), :ruby)
        page = tokens.html(:line_numbers => :inline, :wrap => :div, :css => :class)
      end


      def highlight_test_file(test_file)
        if test_file
          @build = test_file.build
          @project = @build.project

          ui_tests_dir = File.join(@build.artifacts_dir, "ui-tests")
          file_name = test_file.filename
          if file_name.end_with?(".xml")
            if @build.test_syntax_framework == "pytest" || @build.test_syntax_framework == "unittest" 
              file_name = file_name.sub(".xml", ".py")
            elsif @build.test_syntax_framework == "Mocha"
              file_name = file_name.sub(".xml", ".js")              
            elsif @build.test_syntax_framework == "VSTest"
              file_name = file_name.sub(".xml", ".cs")              
            elsif @build.test_syntax_framework == "JUnit"
              file_name = file_name.sub(".xml", ".java")              
            end
          end          
          highlight_test_file_under_ui_tests_folder(ui_tests_dir, file_name)
        end
      end

      def highlight_test_file_under_ui_tests_folder(ui_tests_dir, file_name)
        test_file_content = nil
        if file_name && File.exist?(file_name)
          test_file_content = File.read(file_name)
        elsif File.exist?(File.join(ui_tests_dir, "spec"))
          test_file_content = File.read(File.join(ui_tests_dir, "spec", file_name))
        else
          test_file_content = File.read(File.join(ui_tests_dir, file_name))
        end
        highlight_code(test_file_content)
      end

      def highlight_code(code, opts = {})
        require 'coderay'
        tokens = CodeRay.scan(code, :ruby)
        if opts[:line_number_start] && opts[:line_number_start].to_i > 0
          page = tokens.html(:line_numbers => :inline, :wrap => :div, :css => :class, :line_number_start => opts[:line_number_start])
        else
          page = tokens.html(:line_numbers => :inline, :wrap => :div, :css => :class)
        end
      end

      def highlight_test_case(test_case)
        require 'coderay'
        tokens = CodeRay.scan(test_case.scripts, :ruby)
        page = tokens.html(:line_numbers => :inline, :wrap => :div, :css => :class, :line_number_start => test_case.start_line || 1)
      end
      
    

      def current_user
        if user_id = session[:user_id]
          @current_user = User.where(:id => user_id).first

        elsif (user_id = cookies[:user_id])

            user = User.find_by(id: user_id)
            if user && user.authenticated?(cookies[:remember_token])
              session[:user_id] = user.id
              @current_user = user
            end

        else
          return nil
        end
      end


      def bar_class(build, entry, idx)
        if build &&  entry[:stage_name] 

          if entry[:stage_name].downcase == "ui test"
            return "bar-main-step-" + ( build.successful  ? "successful" : "failed")
          elsif entry[:stage_name].downcase == "api test"
            return "bar-main-step-" + ( build.successful  ? "successful" : "failed")
          else
            return "bar-#{idx}"        
          end
    
        else
          return "bar-#{idx}"
        end
      end
      
      

      def parse_date_range(parameters, default = "today")
        start_date_str = Date.today.strftime('%Y-%m-%d')
        end_date_str = (Date.today + 1).strftime('%Y-%m-%d')

        the_date_range = parameters[:range] || default
        case the_date_range
          when "today"
            start_date_str = (Date.today).strftime('%Y-%m-%d')
          when "since_yesterday"
            start_date_str = (Date.today - 1).strftime('%Y-%m-%d')
          when "last_7_days"
            start_date_str = (Date.today - 7).strftime('%Y-%m-%d')
          when "last_2_weeks"
            start_date_str = (Date.today - 14).strftime('%Y-%m-%d')
          when "last_month"
            start_date_str = (Date.today - 30).strftime('%Y-%m-%d')
          when "last_quarter"
            start_date_str = (Date.today - 90).strftime('%Y-%m-%d')
          when "last_year"
            start_date_str = (Date.today - 365).strftime('%Y-%m-%d')
          when "all"
            start_date_str = (Date.today - 365 * 100).strftime('%Y-%m-%d')
        end
        return start_date_str, end_date_str
      end

      def get_mime_type(name)
        case name.downcase
          when /\.html$/
            'text/html'
          when /\.js$/
            'text/javascript'
          when /\.css$/
            'text/css'
          when /\.gif$/
            'image/gif'
          when /(\.jpg|\.jpeg)$/
            'image/jpeg'
          when /\.png$/
            'image/png'
          when /\.zip$/
            'application/zip'
          else
            'text/plain'
        end
      end
       

    end

    helpers ApplicationHelper
	end
end
