require "devops-client/handler/helpers/http_utils"
require 'devops-client/helpers/string_helper'

# fetches resources list along with table
# Rewrite this to avoid dependency on handlers
module Helpers
  class ResourcesFetcher
    include HttpUtils

    # have the same meaning as in handlers
    attr_reader :username, :password, :options, :host

    def initialize(options)
      @host = "http://#{options.fetch(:host)}"
      @options = options.fetch(:handler_options)
      @auth = options.fetch(:auth)

      # username, password and options are used to perform http queries with module HttpUtils
      @username, @password = @auth[:username], @auth[:password]
    end

    def fetch(collection_name, *args)
      build_handler(collection_name).list_handler(*args)
    end

    def fetch_with_table(collection_name, *args)
      handler = build_handler(collection_name)
      handler.command = :list
      [handler.list_handler(*args), handler.outputter.table]
    end

    def show_list_data_with_table(collection_name, data)
      handler = build_handler(collection_name)
      handler.command = :list
      handler.instance_variable_set('@list', data)
      [data, handler.outputter.table]
    end

    def fetch_by_command_with_table(collection_name, command, args={}, options={})
      handler = build_handler(collection_name)
      handler.command = command
      args.each {|key, val| handler.instance_variable_set("@#{key}", val) }
      return handler.send("#{command}_handler"), handler.outputter.output(options)
    end

    def fetch_project(project_id)
      @fetched_projects = {}
      if cached = @fetched_projects[project_id]
        cached
      else
        @fetched_projects[project_id] = get("/project/#{project_id}")
      end
    end

    def fetch_provider_accounts(provider)
      handler = build_handler('provider')
      [handler.accounts_handler(provider), handler.outputter.output(output_type: :accounts, provider: provider)]
    end

    def fetch_category(project, environment_name, category)
      environment = fetch_project(project)['environments'].detect do |env|
        env['id'] == environment_name
      end
      environment['categories'].detect {|cat| cat['id'] == category }
    end

    private

    def build_handler(collection_name)
      require_handler_file(collection_name)

      handler = resource_handler_klass(collection_name).new(host, self.options)
      handler.auth = @auth
      handler
    end

    def require_handler_file(collection_name)
      require "devops-client/handler/#{collection_name}"
    end

    def resource_handler_klass(collection_name)
      class_name = StringHelper.camelize(collection_name)
      Object.const_get(class_name)
    end
  end
end
