require 'lib/executors/stack_executor'

class StackBootstrapWorker < Worker

  # @options:
  #   'stack_attributes', required
  #   'without_bootstrap', optional. false by default
  #   'skip_rollback', optional. false by default
  def perform(options)
    call do
      puts_and_flush JSON.pretty_generate(options)
      stack_attrs = options.fetch('stack_attributes')
      without_bootstrap = options['without_bootstrap'] || false
      skip_rollback = options['skip_rollback'] || false
      @current_user = stack_attrs['owner']

      set_task_data({
        "created_by" => stack_attrs['owner'],
        "project" => stack_attrs["project"],
        "environment" => stack_attrs["environment"],
        "type" => ::Devops::Model::JobTask::STACK_TYPE,
        "subtasks" => [],
        "stack" => stack_attrs['name']
      })

      executor.create_stack(stack_attrs)
      if !executor.wait_till_stack_is_created
        puts_and_flush "Stack creating error"
        return 1
      end

      begin
        executor.persist_new_servers
        if without_bootstrap
          puts_and_flush "\n\nBootstrap has been skipped. Stack has been successfully created."
          0
        else
          bootstrap_or_rollback_if_failed(skip_rollback: skip_rollback)
        end
      rescue StandardError => e
        puts_and_flush "\nAn error occured."
        rollback_stack! unless skip_rollback
        raise e
      end
    end
  end

  private

  def executor
    @executor ||= Devops::Executor::StackExecutor.new(out: out, current_user: @current_user)
  end

  def bootstrap_or_rollback_if_failed(options)
    bootstrap_result = executor.bootstrap_just_persisted(jid)
    puts_and_flush Devops::Messages.t("worker.stack_bootstrap.bootstrap_result.#{bootstrap_result.reason}")
    if bootstrap_result.bootstrap_error? && !options[:skip_rollback]
      rollback_stack!
    end
    bootstrap_result.code
  end

  def rollback_stack!
    puts_and_flush "\nStart rollback of a stack"
    begin
      executor.delete_stack
      puts_and_flush "Stack rollback has been completed"
    rescue StandardError
      puts_and_flush "Stack rollback failed"
    end
  end

end
