

module BuildWise
  
  class AddCommand
    EXAMPLE_CONFIG = File.expand_path(File.dirname(__FILE__) + '/config.example.yml')

    def initialize(path, cli_options = {})


      @path, @cli_options = path, cli_options
    end

    def run
      if @cli_options[:scm] && @cli_options[:scm][:type]
        scm_type = @cli_options[:scm][:type]
      else
        scm_type = BuildWise::SCM.guess_type(@path)  || 'git'
      end


      application_name = @cli_options[:application_name] || @cli_options[:identifier] || extract_project_name(@path)
      config_name = "#{BUILDWISE_HOME}/config/#{application_name}.xml"
      project_config = BuildWise::ProjectConfiguration.new(config_name)

      scm = BuildWise::SCM.get(scm_type).new(@path, project_config)
      project_config.scm_type = scm_type
      project_config.scm_url = scm.url

      say "Can't find any #{scm_type} application under #{@path}" unless scm
      
      say "SCM URL cannot be determined for path #{@path}, SCM type: |#{scm_type}|, #{scm}, #{scm.url}" if project_config.scm_url.nil?

      if @cli_options[:scm]
        project_config.scm_user = @cli_options[:scm]["user_name"] if @cli_options[:scm]["user_name"]
        project_config.scm_password = @cli_options[:scm]["password"] if @cli_options[:scm]["password"]
      end
    
      project_config.application_root = @cli_options[:application_root]


      if File.exist?(config_name)
        puts "Application #{application_name} | #{config_name} already present in BuildWise" 
        raise  "Application #{application_name} | #{config_name} already present in BuildWise" 
      end
      
      if @cli_options[:builder]

        if @cli_options[:builder]["steps_json"] && @cli_options[:builder]["steps_json"].strip.start_with?("[")

          steps_json_obj = JSON.parse(@cli_options[:builder]["steps_json"].strip)
          steps_json_obj.each do |a_step|
            the_step = ::BuildWise::BuildStep.new(a_step["name"])
            the_step.builder = a_step["builder"]
            the_step.order = a_step["order"]
            the_step.task =  a_step["task"]
            the_step.enabled = true      
            the_step.attributes["test_syntax_framework"] = a_step["test_framework"]
            project_config.build_steps << the_step
          end          
          
        else 
          
          if @cli_options[:builder]["migrate_database_task"]
            the_step = ::BuildWise::BuildStep.new("Migrate DataBase")
            the_step.builder = "Rake"
            the_step.order = "5"
            the_step.task = @cli_options[:builder]["migrate_database_task"]
            the_step.enabled = true      
            project_config.build_steps << the_step
          end

          if @cli_options[:builder]["unit_test_task"]          
            the_step = ::BuildWise::BuildStep.new("Unit Test")
            the_step.builder = "Rake"
            the_step.order = "15"
            the_step.task = @cli_options[:builder]["unit_test_task"]
            the_step.enabled = true      
          end

          if @cli_options[:builder]["main_testing_step_task"]
            the_step = ::BuildWise::BuildStep.new( @cli_options[:builder]["main_testing_step_name"] )
            the_step.builder = "Rake"
            the_step.order = "20"
            the_step.task = @cli_options[:builder]["main_testing_step_task"]
            the_step.enabled = true      
            if @cli_options[:builder]["main_testing_step_framework"]
              the_step.attributes["test_syntax_framework"] = @cli_options[:builder]["main_testing_step_framework"]
            else

              the_step.attributes["test_syntax_framework"] = the_step.attributes["ui_test_framework"] = @cli_options[:builder]["ui_test_framework"]
            end
            the_step.add_attribute("remove_suite_name_from_test_case", true)

            the_step.attributes["ui_test_framework"]  = the_step.attributes["test_syntax_framework"]          
            project_config.build_steps << the_step
          
          else
          

            if @cli_options[:builder]["api_test_task"]
              the_step = ::BuildWise::BuildStep.new("API Test")
              the_step.builder = "Rake"
              the_step.order = "20"
              the_step.task = @cli_options[:builder]["api_test_task"]
              the_step.enabled = true      
              if @cli_options[:builder][:ui_test_framework]
                the_step.attributes["ui_test_framework"] = @cli_options[:builder][:ui_test_framework]
              end
              project_config.build_steps << the_step
            end

            if @cli_options[:builder]["load_test_task"] && !@cli_options[:builder]["load_test_task"].strip.empty? 
              the_step = ::BuildWise::ProjectConfiguration.default_load_test_step.dup
              the_step.task = @cli_options[:builder]["ui_test_task"]
              the_step.enabled = true
              the_step.attributes["ui_test_framework"] = "RSpec"
              project_config.build_steps << the_step

            elsif @cli_options[:builder]["preformance_test_task"]
              the_step = ::BuildWise::ProjectConfiguration.default_ui_test_step.dup            
              the_step.task = @cli_options[:builder]["ui_test_task"]
              the_step.enabled = true          
              if @cli_options[:builder]["ui_test_framework"]
                the_step.attributes["ui_test_framework"] =  @cli_options[:builder]["ui_test_framework"]
              end
              project_config.build_steps << the_step
                  
            elsif @cli_options[:builder]["ui_test_task"]
              the_step = ::BuildWise::ProjectConfiguration.default_ui_test_step.dup            
              the_step.task = @cli_options[:builder]["ui_test_task"]
              the_step.enabled = true          
              if @cli_options[:builder]["ui_test_framework"]
                the_step.attributes["ui_test_framework"] =  @cli_options[:builder]["ui_test_framework"]
              end
              project_config.build_steps << the_step
            end

          end
        end
        
        
        if @cli_options[:builder]["prepare_command"] && !@cli_options[:builder]["prepare_command"].strip.empty? 
          project_config.builder_prepare_command = @cli_options[:builder]["prepare_command"].strip
        end
        
        if @cli_options[:builder]["cleanup_command"] && !@cli_options[:builder]["cleanup_command"].strip.empty? 
          project_config.builder_cleanup_command = @cli_options[:builder]["cleanup_command"].strip
        end
                
      end

      if @cli_options[:ui_tests]
        project_config.ui_tests_dir = @cli_options[:ui_tests]["test_dir"] if @cli_options[:ui_tests]["test_dir"]
        project_config.ui_tests_report_dir = @cli_options[:ui_tests]["report_dir"] if @cli_options[:ui_tests]["report_dir"]
      end

      if @cli_options[:parallel]
        project_config.is_parallel = true
        project_config.app_name = @cli_options[:parallel]["app_name"] if @cli_options[:parallel]["app_name"]
        project_config.agent_work_dir = @cli_options[:parallel]["agent_work_dir"] if @cli_options[:parallel]["agent_work_dir"]
      end

      if @cli_options[:load]
        project_config.is_load_testing = true
        project_config.load_server_url = @cli_options[:load]["load_server_url"] if @cli_options[:load]["load_server_url"]
        project_config.load_max_agent_count = @cli_options[:load]["max_agent_count"] if @cli_options[:load]["max_agent_count"]
        project_config.load_max_iteration_count = @cli_options[:load]["max_iteration_count"] if @cli_options[:load]["max_iteration_count"]
        project_config.load_max_duration = @cli_options[:load]["app_name"] if @cli_options[:load]["max_duration"]
        project_config.load_repeat_times_within_test = @cli_options[:load]["repeat_times_within_test"] if @cli_options[:load]["repeat_times_within_test"]
        project_config.load_load_criteria_error_rate = @cli_options[:load]["load_criteria_error_rate"] if @cli_options[:load]["load_criteria_error_rate"]                
      end

      project_config.ui_tests_local_working_dir = @path
      
      if project_config.ui_tests_dir
        project_config.ui_tests_local_working_dir = File.join(@path, project_config.ui_tests_dir)
      end
      
      if project_config.build_steps.empty?

        project_config.build_steps << ::BuildWise::ProjectConfiguration.default_test_stats_step.dup
        project_config.build_steps << ::BuildWise::ProjectConfiguration.default_ui_test_step.dup        
      end

      project_config.save
      puts "Application '#{application_name}' has been added to BuildWise successfully" unless @cli_options[:quiet]
    end

    private

    def extract_project_name(path)
      path = File.expand_path(path) if test(?d, path)
      File.basename(path).strip.gsub(/\.git$/, '')
    end

    def create_example_config
      FileUtils.mkpath(BUILDWISE_HOME) unless test(?d, BUILDWISE_HOME)
      FileUtils.cp(EXAMPLE_CONFIG, CONFIG_FILE) unless test(?f, CONFIG_FILE)
    end
  end

end  