require 'tracker_api'

class PivotalTrackerClient

  GEORDI_GLOBAL_CONFIG_PATHNAME = File.join(Dir.home, '.config/geordi/global.yml').freeze
  MissingAPIKeyError = Class.new(StandardError)

  def initialize(env)
    token = api_key_from_geordi
    if token.blank?
      raise MissingAPIKeyError, 'Missing Pivotal Tracker API key. Please configure it with `geordi commit`.'
    end

    @client = TrackerApi::Client.new(token: token)
    @env = env
  end

  def cli_check_deploy_tasks(before_or_after, prompt)
    deploy_task_stories = cli_fetch_deploy_task_stories(before_or_after)

    if deploy_task_stories.any?
      puts "#{before_or_after.capitalize} deploy tasks found."

      deploy_task_stories.each do |project, stories|
        puts "\n# Project: #{project.name}"
        puts stories.map { |story| "#{story.url} · #{story.name}" }
      end
      puts
      puts Airbrussh::Colors.yellow("> #{prompt.capitalize}")
      puts 'After performing a task, please remove the deploy task label from that story.'

      if before_or_after.to_s == 'before'
        puts
        print 'Continue deployment? [yN] '
        if $stdin.gets.strip.downcase != 'y'
          puts 'Cancelled.'
          abort
        end
      end
    else
      puts "No #{before_or_after} deploy tasks found."
    end
  end

  def cli_fetch_deploy_task_stories(before_or_after)
    loading_message = "Checking Pivotal Tracker for #{before_or_after} deploy tasks ..."
    deploy_task_stories = []
    tag = "#{before_or_after} #{@env} deploy"

    begin
      print loading_message
      deploy_task_stories = stories_by_project(tag: tag)
    rescue MissingAPIKeyError, TrackerApi::Errors::ClientError, TrackerApi::Errors::ServerError => e
      cli_overwrite(loading_message)
      puts "Error: #{e.message}"
      puts
      puts 'A connection to Pivotal Tracker could not be established. Please check deploy tasks manually.'
      print 'Continuing deployment when you are ready. '
      $stdin.gets
    else
      cli_overwrite(loading_message)
    end

    deploy_task_stories
  end

  def stories_by_project(tag:)
    projects.each_with_object({}) do |project, hash|
      relevant_story_states = (@env == 'production') ? 'accepted' : 'accepted,delivered,finished'
      filter = %(label:"#{tag}" state:#{relevant_story_states})
      stories = project.stories(filter: filter)

      hash[project] = stories if stories.any?
    end
  end

  private

  def cli_overwrite(text)
    print "\r" + (' ' * text.length) + "\r"
  end

  def projects
    @projects ||= begin
      file = YAML.load_file(Pathname(__dir__).join('../../.geordi.yml'))
      file['pivotal_tracker_project_ids'].split(',').map do |id|
        @client.project(id.strip)
      end
    end
  end

  def api_key_from_geordi
    if File.file?(GEORDI_GLOBAL_CONFIG_PATHNAME)
      geordi_settings = YAML.load_file(GEORDI_GLOBAL_CONFIG_PATHNAME)
      geordi_settings['pivotal_tracker_api_key'] if geordi_settings&.key?('pivotal_tracker_api_key')
    end
  end

end
