require_relative "worker"

require "json"
require "fileutils"
require "commands/status"

class ProjectTestWorker < Worker
  include StatusCommands

  def perform(params)
    user = params.fetch('user')
    project_name = params.fetch('project')
    deploy_env_name = params.fetch('deploy_env')

    #TODO:
    call() do |out, file|
      DevopsLogger.logger.info "Test project '#{project_name}' and env '#{deploy_env_name}' (user - #{user})"
      project = mongo.project(project_name)
      env = project.deploy_env(deploy_env_name)
      report = save_report(user, project_name, deploy_env_name)

      executor = Devops::Executor::ServerExecutor.new(nil, out)
      executor.project = project
      executor.report = report
      executor.deploy_env = env

      result = {:servers => []}
      project.deploy_envs = [ env ]
      result[:project] = project.to_hash
      status = 0
      sr = {}
      t1 = Time.now
      out << "\n=== Create server ===\n"
      out.flush
      if executor.create_server("without_bootstrap" => true)
        out << "\n=== Create server - OK ===\n"
        out.flush
        t2 = Time.now
        s = executor.server
        sr[:id] = s.id
        sr[:create] = {:status => true}
        sr[:create][:time] = time_diff_s(t1, t2)
        DevopsLogger.logger.info "Server with parameters: #{s.to_hash.inspect} is running"
        out << "\n=== Bootstrap ===\n"
        out.flush
        r = executor.bootstrap({})
        t1 = Time.now
        sr[:name] = s.name
        if r == 0
          out << "\n=== Bootstrap - OK ===\n"
          out.flush
          sr[:bootstrap] = {:status => true}
          sr[:bootstrap][:time] = time_diff_s(t2, t1)
          DevopsLogger.logger.info "Server with id '#{s.id}' is bootstraped"
          out << "\n=== Check server ===\n"
          out.flush
          if executor.check_server
            # mongo.server_insert s
            out << "\n=== OK, server has been inserted ===\n"
            out.flush
          end
        else
          status = 2
          out << "\n=== Bootstrap - FAIL ===\n"
          out.flush
          sr[:bootstrap] = {:status => false}
          sr[:bootstrap][:return_code] = r
        end

        t1 = Time.now
        out << "\n=== Delete server ===\n"
        out.flush
        r = executor.delete_from_chef_server(s.name)
        begin
          r[:server] = s.provider_instance.delete_server s
          out << "\n=== Delete server - OK ===\n"
          out.flush
        rescue Fog::Compute::OpenStack::NotFound, Fog::Compute::AWS::Error
          status = 3
          out << "\n=== Delete server - FAIL ===\n"
          out.flush
          r[:server] = "Server with id '#{s.id}' not found in '#{s.provider_instance.name}' servers"
          DevopsLogger.logger.warn r[:server]
        end
        mongo.server_delete s.id
        t2 = Time.now
        sr[:delete] = {:status => true}
        sr[:delete][:time] = time_diff_s(t1, t2)
      else
        status = 1
        out << "\n=== Create server - FAIL ===\n"
        out.flush
        sr[:create] = {:status => false}
      end
      result[:servers].push sr
      out << "\n\n#{result.to_json}"
      status
    end
  end

  private

  def save_report(user, project_name, deploy_env_name)
    update_report(
      "created_by" => user,
      "project" => project_name,
      "deploy_env" => deploy_env_name,
      "type" => Devops::Model::JobTask::PROJECT_TEST_TYPE
    )
  end
end
