require "devops-client/handler/handler"
require "devops-client/options/server_options"
require "devops-client/output/server"
require "devops-client/handler/project"

class Server < Handler

  output_with Output::Server

  def initialize(host, def_options={})
    @host, @options = host, def_options
  end

  def handle
    @options_parser = ServerOptions.new(ARGV, @options)
    @command, @options, @args = @options_parser.parse_options_for!
    extract_parameters
    case @command
    when :list
      list_handler
      output
    when :show
      show_handler
      output(server: @server_id)
    when :create
      create_handler
    when :delete
      delete_handler
    when :delete_list
      delete_list_handler
    when :bootstrap
      bootstrap_handler
    when :unbootstrap
      unbootstrap_handler
    when :sync
      sync_handler
    when :pause
      pause_handler
    when :unpause
      unpause_handler
    when :reserve
      reserve_handler
    when :unreserve
      unreserve_handler
    when :add
      add_static_handler
    when :add_and_bootstrap_list
      add_and_bootstrap_list_handler
    end
  end

  def list_handler
    params = {}
    params["provider"] = @provider if @provider
    @list = get("/servers", params)
  end

  def create_handler

    q = {
      project: @project,
      environment: @environment,
      category: @category
    }

    [:ssh_key, :without_bootstrap, :name, :groups, :skip_rollback, :private_ip].each do |k|
      q[k] = self.options[k] unless self.options[k].nil?
    end

    job_ids = post "/server", q
    reports_urls(job_ids)
  end

  def delete_handler
    if question(I18n.t("handler.server.question.delete", :id => @server_id))
      jobs_ids = delete("/server/#{@server_id}", options) # returns array with one job id, actually
      reports_urls(jobs_ids)
    end
  end

  # this method differs from #delete_handler in this:
  # it deletes multiple servers at once and takes servers ids instead of node names.
  # Timur said we planned to transfer all server requests to using ids by default, that's why
  # later we could get rid of #delete_list method.
  def delete_list_handler
    if question(I18n.t("handler.server.question.delete_list", ids: @server_id.join(', ')))
      servers_jobs = post("/servers/delete", {servers_ids: @server_id})
      servers_jobs.each do |server_id, job_id|
        puts "Report for deleting #{server_id}: #{report_url(job_id)}"
      end
    end
    nil
  end

  def show_handler
    @show = get("/server/#{@server_id}")
  end

  def bootstrap_handler
    q = {}
    [:cm_name, :bootstrap_template, :run_list].each do |k|
      q[k] = self.options[k] unless self.options[k].nil?
    end
    if q.has_key?(:run_list)
      abort unless Project.validate_run_list(q[:run_list])
    end
    job_ids = post "/server/#{@server_id}/bootstrap", q
    reports_urls(job_ids)
  end

  def unbootstrap_handler
    if question(I18n.t("handler.server.question.unbootstrap", :id => @server_id))
      job_ids = post("/server/#{@server_id}/unbootstrap")
      reports_urls(job_ids)
    end
  end

  def add_static_handler # add <project> <env> <private_ip> <ssh_username> <keyname> --public-ip <public_ip>
    q = {
      project: @project,
      environment: @environment,
      category: @category,
      private_ip: @ip,
      remote_user: @ssh_user,
      key: @key_id,
      name: @name
    }
    q[:public_ip] = self.options[:public_ip] if self.options[:public_ip]
    post "/server/add", q
  end

  def add_and_bootstrap_list_handler
    project, env, user, key, ips_file_path = @args[2..6]
    r = inspect_parameters @options_parser.add_and_bootstrap_list_params, project, env, user, key, ips_file_path
    unless r.nil?
      @options_parser.invalid_add_and_bootstrap_list_command
      abort(r)
    end
    q = {
      project: project,
      deploy_env: env,
      remote_user: user,
      key: key,
      ips_with_names: get_file_contents(ips_file_path)
    }
    q[:public_ip] = options[:public_ip] if options[:public_ip]
    report_ids = post "/server/add_and_bootstrap_servers", q
    reports_urls(report_ids)
  end

  def pause_handler
    post "/server/#{@server_id}/pause"
  end

  def unpause_handler
    post "/server/#{@server_id}/unpause"
  end

  def reserve_handler
    post "/server/#{@server_id}/reserve"
  end

  def unreserve_handler
    post "/server/#{@server_id}/unreserve"
  end

end
