require 'devops-client/handler/helpers/resources_fetcher'
require 'devops-client/handler/helpers/input_utils'
require 'devops-client/output/project'

module Helpers
  class ResourcesSelector

    include InputUtils

    def initialize(fetcher)
      raise "fetcher should be instance of ResourcesFetcher" unless fetcher.is_a?(ResourcesFetcher)
      @fetcher = fetcher
    end

    def select_available_provider(options={})
      providers = @fetcher.fetch('provider')
      providers -= options[:except] if options[:except]
      choose_item_from_list(I18n.t("headers.provider"), providers)
    end

    def select_available_bootstrap_template
      templates, table = @fetcher.fetch_by_command_with_table('chef', :bootstrap_templates)
      select_item_from_table(I18n.t("headers.bootstrap_templates"), templates, table)
    end

    def select_available_provider_account provider
      accounts, table = @fetcher.fetch_by_command_with_table('provider', :accounts, {provider: provider})
      select_item_from_table(I18n.t("headers.provider_account"), accounts, table)
    end

    def select_available_provider_account_image provider, provider_account
      images, table = @fetcher.fetch_by_command_with_table('provider', :images, {provider: provider, account: provider_account})
      select_item_from_table(I18n.t("headers.image"), images, table)
    end

    def select_available_project
      projects, table = @fetcher.fetch_with_table('project')
      project = select_item_from_table(I18n.t("headers.project"), projects, table)
      project['name']
    end

    def select_available_env(project_id)
      project = @fetcher.fetch_project(project_id)
      outputter = Output::Project.new(project, {output_type: :show, with_num: true})
      env = select_item_from_table("Select deploy env", project['deploy_envs'], outputter.table)
      env['identifier']
    end

    def select_available_stack_template(options={})
      stack_templates, table = @fetcher.fetch_with_table('stack_template', options[:provider])
      stack_template = select_item_from_table(I18n.t("headers.stack_template"), stack_templates, table)
      stack_template['id']
    end

    def select_available_flavor(args)
      flavors, table = @fetcher.fetch_by_command_with_table('provider', :flavors, args, {provider: args[:provider], account: args[:account]})
      abort(I18n.t("handler.provider.flavor.list.empty")) if flavors.empty?

      select_item_from_table(I18n.t("choose.flavor"), flavors, table)["id"]
    end

    def select_available_image(args)
      images, table = @fetcher.fetch_by_command_with_table('image', :list, args, {provider: args[:provider], account: args[:account]})
      abort(I18n.t("handler.provider.images.list.empty")) if images.empty?

      select_item_from_table(I18n.t("choose.image"), images, table)["id"]
    end

    def select_available_vpc(args)
      vpcs, table = @fetcher.fetch_by_command_with_table('provider', :vpc, args)
      abort(I18n.t("handler.provider.vpc.list.empty")) if vpcs.empty?

      select_item_from_table(I18n.t("choose.vpc"), vpcs, table)["vpc_id"]
    end

    def select_available_network(args, options={})
      networks, table = @fetcher.fetch_by_command_with_table('provider', :networks, args)
      select_item_from_table(I18n.t("choose.network"), networks, table)["subnetId"]
    end

    def select_available_networks(args)
      networks, table = @fetcher.fetch_by_command_with_table('provider', :networks, args)

      selected_networks = select_items_from_table(I18n.t("choose.networks"), networks, table)
      selected_networks.map {|network| network['name']}
    end

    # options:
    #   :data - list of strings
    def select_available_users(options={})
      title = options[:label] || I18n.t("input.users.label")
      users, table = if options[:data]
        @fetcher.show_list_data_with_table('user', options[:data].map{|v| {'id' => v}})
      else
        @fetcher.fetch_with_table('user')
      end

      users = select_items_from_table(title, users, table)
      users.map {|user| user['id']}
    end

    def select_available_ssh_keys(options={})
      ssh_keys, table = @fetcher.fetch_with_table('key')

      select_item_from_table(I18n.t("choose.ssh_key"), ssh_keys, table)['id']
    end

    def select_available_security_groups(args)
      groups, table = @fetcher.fetch_by_command_with_table('provider', :security_groups, args)

      # somewhy groups returned as a hash, not array
      groups_array = []
      groups.each do |group_id, group_attrs|
        group_attrs['id'] = group_id
        groups_array << group_attrs
      end

      default_index = groups_array.index {|t| t['id'] == 'default'}
      select_items_from_table(I18n.t("choose.security_groups"), groups_array, table, default: 'default', default_index: default_index).map{|g| g["id"]}
    end

    def select_available_roles used_roles=[]
      roles, table = @fetcher.fetch_with_table('role')
      roles.delete_if{|role| used_roles.include?(role["id"])} unless used_roles.empty?
      roles = select_items_from_table(I18n.t("headers.role"), roles, table)
      roles.map{|r| r['id']}
    end

    def select_user_roles used_roles
      roles, table = @fetcher.fetch_with_table('role')
      roles.select{|role| used_roles.include?(role["id"])}
      roles = select_items_from_table(I18n.t("headers.role"), roles, table)
      roles.map{|r| r['id']}
    end

  end
end
