class Idlc::Deploy::Config

def add_deployment_var(key, value)

def add_deployment_var(key, value)
  ENV["TF_VAR_#{key}"] = value
end

def configure_state(bucket, sub_bucket, working_directory)

def configure_state(bucket, sub_bucket, working_directory)
  validate_environment
  tf_version = Terraform::Binary::config.version.split('.')
  configure_tfstatev8(bucket, sub_bucket, working_directory) if tf_version[0].to_i == 0 && tf_version[1].to_i <= 8
  configure_tfstatev9(bucket, sub_bucket, working_directory) if tf_version[0].to_i == 0 && tf_version[1].to_i > 8
  configure_tfstatev10(bucket, sub_bucket, working_directory) if tf_version[0].to_i > 0
end

def configure_tfstatev10(bucket, sub_bucket, working_directory)

def configure_tfstatev10(bucket, sub_bucket, working_directory)
  args = []
  args << "-backend-config=\"bucket=#{bucket}\""
  args << "-backend-config=\"key=#{sub_bucket}/terraform.tfstate\""
  args << "-backend-config=\"region=#{@region}\""
  args << "-force-copy"
  Terraform::Binary::Command.run("-chdir=\"#{working_directory}\" init #{args.join(' ')}")
end

def configure_tfstatev8(bucket, sub_bucket, working_directory)

def configure_tfstatev8(bucket, sub_bucket, working_directory)
  args = []
  args << '-backend=s3'
  args << '-backend-config="acl=private"'
  args << "-backend-config=\"bucket=#{bucket}\""
  args << '-backend-config="encrypt=true"'
  args << "-backend-config=\"key=#{sub_bucket}/terraform.tfstate\""
  args << "-backend-config=\"region=#{@region}\""
  Terraform::Binary.remote("config #{args.join(' ')}")
  Terraform::Binary.get("-update #{working_directory}")
end

def configure_tfstatev9(bucket, sub_bucket, working_directory)

def configure_tfstatev9(bucket, sub_bucket, working_directory)
  args = []
  args << "-backend-config=\"bucket=#{bucket}\""
  args << "-backend-config=\"key=#{sub_bucket}/terraform.tfstate\""
  args << "-backend-config=\"region=#{@region}\""
  args << "-force-copy"
  Terraform::Binary.init("#{args.join(' ')} #{working_directory}")
end

def get_deployment_output(key)

def get_deployment_output(key)
  `#{Terraform::Binary::Command.binary} output #{key}`.strip!
end

def get_deployment_var(key)

def get_deployment_var(key)
  ENV["TF_VAR_#{key}"]
end

def get_env_metadata(env_key)

def get_env_metadata(env_key)
  client = Idlc::AWSLambdaProxy.new()
  request = {
    service: 'deploy',
    method: 'GET',
    lambda: 'metadata',
    pathParameters: {
      jobName: env_key
    }
  }
  metadata = client.fetch(request)['deployments'].first
  request = {
    service: 'config',
    method: 'GET',
    lambda: "accounts",
    pathParameters: {
      accountName: metadata['environment']['account_alias']
    }
  }
  account = client.fetch(request)
  metadata['account'] = account['accounts'].first
  request = {
    service: 'config',
    method: 'GET',
    lambda: "applications",
    pathParameters: {
      appName: metadata['environment']['application_name'].downcase
    }
  }
  application = client.fetch(request)
  metadata['application'] = application['applications'].first
  # find db and fs instance
  metadata['instances'].each do |instance|
    if (instance['hostname'].start_with?('db') || instance['hostname'].start_with?('rds'))
      metadata['db_instance'] = instance
    end
    if (instance['hostname'].start_with?('fs'))
      metadata['fs_instance'] = instance
    end
  end
  metadata
end

def get_instance

def get_instance
  # Get the current instance id from the instance metadata.
  metadata_endpoint = 'http://169.254.169.254/latest/meta-data/'
  instance_id = Net::HTTP.get( URI.parse( metadata_endpoint + 'instance-id' ) )
  # Create instance object with instance id.
  instance = Aws::EC2::Instance.new( id: instance_id, region: ENV['AWS_REGION'] )
  # save some instance info
  i = {}
  i['instance_id'] = instance_id
  # save tags
  i['tags'] = {}
  instance.tags.each do |tag|
    # Grab all of the tags as node attributes
    i['tags'][tag.key] = tag.value
  end
  i
end

def get_region

def get_region
  # Get the current az from the instance metadata.
  metadata_endpoint = 'http://169.254.169.254/latest/meta-data/'
  az = Net::HTTP.get( URI.parse( metadata_endpoint + 'placement/availability-zone' ) )
  # return
  az[0..-2]
end

def initialize(region)

def initialize(region)
  @region = region
  Idlc::Utility.check_for_creds
rescue Idlc::Utility::MissingCredentials => e
  msg("WARN: #{e.message}\nFalling back to implicit authentication.")
end

def load_tasks

def load_tasks
  Dir.glob("#{__dir__}/tasks/*.rake").each do |task_file|
    load task_file
  end
end

def parse(config_file)

def parse(config_file)
  raise ArgumentError, "#{config_file} does not exist" unless File.exist? config_file
  Config.add_deployment_var('inf_config_file', config_file)
  # Parse the config file
  YAML.load_file(config_file)['configuration'].each do |section, body|
    next if section == 'dynamics' # skip the dynamics sections
    next unless (section =~ /overrides/).nil? # skip the app overrides sections
    next if body.nil?
    body.each do |key, value|
      debug("#{section}: #{key} = #{value}")
      Config.add_deployment_var(key, value)
    end
  end
end

def set_hostname (instance)

def set_hostname (instance)
  hostname = instance['tags']['Name']
  unless (instance['tags']['Name'].start_with?('db') || instance['tags']['Name'].start_with?('fs'))
    # Use instance id for unique hostname
    hostname = instance['tags']['Name'][0..4] + '-' + instance['instance_id'][2..10]
  end
  ec2_instance = Aws::EC2::Instance.new( id: instance['instance_id'], region: ENV['AWS_REGION'] )
  ec2_instance.create_tags(
    dry_run: false,
    tags: [ # required
      {
        key: 'hostname',
        value: hostname
      }
    ]
  )
  #return
  hostname
end

def validate_environment

def validate_environment
  %w[
    TF_VAR_tfstate_bucket
    TF_VAR_job_code
    TF_VAR_env
    TF_VAR_domain
  ].each do |var|
    raise "missing #{var} in environment" unless ENV.include? var
  end
end

def whoami

def whoami
  # This method is meant to be run on an instance inside of a chef run to
  # provision instance and environment metadata.
  ENV['AWS_REGION'] = get_region
  # Get the current instance id from the instance metadata.
  instance = get_instance
  # return environment metadata
  metadata = get_env_metadata(instance['tags']['environment_key'])
  metadata['hostname'] = set_hostname(instance)
  metadata
end