# frozen_string_literal: true

# AWS Helpers
def deploy_env
  env(:deploy_env).split(',').map(&:strip).map(&:to_sym)
end

def ecs_client(region:, account: env(:deploy_aws_account), assume_role: env(:deploy_assume_role), session_name: "updating-#{env :task_family}-to-#{env :image_version}")
  region = mapped_region(region)

  if assume_role.nil? || assume_role.empty?
    Aws::ECS::Client.new region: region, credentials: Aws::InstanceProfileCredentials.new
  else
    Aws::ECS::Client.new region: region, credentials: Aws::AssumeRoleCredentials.new(
      client: Aws::STS::Client.new(region: region),
      role_arn: "arn:aws:iam::#{account}:role/#{assume_role}",
      role_session_name: session_name
    )
  end
end

def ecs_cluster_arn(region:, name: env(:cluster_name), account: env(:deploy_aws_account))
  "arn:aws:ecs:#{mapped_region(region)}:#{account}:cluster/#{name}"
end

def env(key)
  @env ||= ENV.collect { |name, value| [name.downcase.to_sym, value] }.to_h
  @env[key]
end

def events_client(region:, account: env(:deploy_aws_account), assume_role: env(:deploy_assume_role), session_name: "updating-#{env :task_family}-to-#{env :image_version}")
  region = mapped_region(region)

  if assume_role.nil? || assume_role.empty?
    Aws::CloudWatchEvents::Client.new region: region, credentials: Aws::InstanceProfileCredentials.new
  else
    Aws::CloudWatchEvents::Client.new region: region, credentials: Aws::AssumeRoleCredentials.new(
      client: Aws::STS::Client.new(region: region),
      role_arn: "arn:aws:iam::#{account}:role/#{assume_role}",
      role_session_name: session_name
    )
  end
end

def executor_role_arn(region:)
  "arn:aws:iam::#{env :deploy_aws_account}:role/#{regionalized_role(region: region, key: :executor_role)}"
end

def image
  "#{env :aws_ecr_url}/#{env(:teamcity_project_name).downcase}:#{env :image_version}"
end

def image_version
  env :image_version
end

def mapped_region(region)
  standard_region_mapping[region.to_sym] || region
end

def pretty_region(region:)
  parts = region.to_s.split('-')
  "#{parts[0].upcase}#{parts[1].capitalize}#{parts[2]}"
end

def regionalized_role(region:, key:)
  base = env(key)
  return base unless base =~ /^.*-(.*)-.*$/

  region = mapped_region(region)
  parts = base.split('-')
  "#{parts[0]}-#{pretty_region(region: region)}-#{parts[2]}"[0..62]
end

def regionalized_service_hostname(base:, region:)
  region = mapped_region(region)

  parts = base.split('.', 2)
  "#{parts[0]}-#{region}.#{parts[1]}"
end

# Returns the standard airport code to aws region mappings used by CSI
# @return [Hash<Symbol, String>]
def standard_region_mapping
  @standard_region_mapping ||= {
    bom: 'ap-south-1',
    cdg: 'eu-west-3',
    cle: 'us-east-2',
    dub: 'eu-west-1',
    fra: 'eu-central-1',
    gru: 'sa-east-1',
    iad: 'us-east-1',
    icn: 'ap-northeast-2',
    lhr: 'eu-west-2',
    nrt: 'ap-northeast-1',
    pdx: 'us-west-2',
    sin: 'ap-southeast-1',
    sjc: 'us-west-1',
    syd: 'ap-southeast-2',
    yul: 'ca-central-1'
  }
end

def task_environment(*keys)
  keys.collect { |key| { name: key.to_s.upcase, value: env(key) } }
end

def task_family
  env(:task_family) || env(:teamcity_project_name)
end

def task_definition_arn(region:, account: env(:deploy_aws_account), version: nil)
  ["arn:aws:ecs:#{mapped_region(region)}:#{account}:task-definition/#{task_family}", version].compact.join(':')
end

def task_role_arn(region:)
  "arn:aws:iam::#{env :deploy_aws_account}:role/#{regionalized_role(region: region, key: :task_role)}"
end

# Teamcity Helpers
def log(message)
  puts "##teamcity[message text='#{message}']"
end

def set_param(key, value)
  puts "##teamcity[setParameter name='#{key}' value='#{value}']"
end
