class ElasticAPM::Metadata::CloudInfo

@api private

def fetch!

rubocop:disable Metrics/CyclomaticComplexity
def fetch!
  case config.cloud_provider
  when "aws"
    fetch_aws
  when "gcp"
    fetch_gcp
  when "azure"
    fetch_azure || read_azure_app_services
  when "auto"
    fetch_aws || fetch_gcp || fetch_azure || read_azure_app_services
  when "none"
    nil
  else
    error("Unknown setting for cloud_provider '#{config.cloud_provider}'")
  end
  self
end

def fetch_aws

def fetch_aws
  resp = @client.get(AWS_URI)
  return unless resp.status == 200
  return unless (metadata = JSON.parse(resp.body.to_s))
  self.provider = "aws"
  self.account_id = metadata["accountId"]
  self.instance_id = metadata["instanceId"]
  self.availability_zone = metadata["availabilityZone"]
  self.machine_type = metadata["instanceType"]
  self.region = metadata["region"]
rescue HTTP::TimeoutError, HTTP::ConnectionError
  nil
end

def fetch_azure

def fetch_azure
  resp = @client.headers("Metadata" => "true").get(AZURE_URI)
  return unless resp.status == 200
  return unless (metadata = JSON.parse(resp.body.to_s))
  self.provider = 'azure'
  self.account_id = metadata["subscriptionId"]
  self.instance_id = metadata["vmId"]
  self.instance_name = metadata["name"]
  self.project_name = metadata["resourceGroupName"]
  self.availability_zone = metadata["zone"]
  self.machine_type = metadata["vmSize"]
  self.region = metadata["location"]
rescue HTTP::TimeoutError, HTTP::ConnectionError
  nil
end

def fetch_gcp

def fetch_gcp
  resp = @client.headers("Metadata-Flavor" => "Google").get(GCP_URI)
  return unless resp.status == 200
  return unless (metadata = JSON.parse(resp.body.to_s))
  zone = metadata["instance"]["zone"]&.split("/")&.at(-1)
  self.provider = "gcp"
  self.instance_id = metadata["instance"]["id"].to_s
  self.instance_name = metadata["instance"]["name"]
  self.project_id = metadata["project"]["projectId"]
  self.availability_zone = zone
  self.region = zone.split("-")[0..-2].join("-")
  self.machine_type = metadata["instance"]["machineType"].split("/")[-1]
rescue HTTP::TimeoutError, HTTP::ConnectionError
  nil
end

def initialize(config)

def initialize(config)
  @config = config
  @client = HTTP.timeout(connect: 0.1, read: 0.1)
end

def parse_azure_app_services_owner_name(owner_name)

def parse_azure_app_services_owner_name(owner_name)
  id, rest = owner_name.split('+')
  *_, region = rest.split('-')
  region.gsub!(/webspace.*$/, '')
  [id, region]
end

def read_azure_app_services

def read_azure_app_services
  owner_name, instance_id, site_name, resource_group =
    ENV.values_at(
      'WEBSITE_OWNER_NAME',
      'WEBSITE_INSTANCE_ID',
      'WEBSITE_SITE_NAME',
      'WEBSITE_RESOURCE_GROUP'
    )
  return unless owner_name && instance_id && site_name && resource_group
  self.provider = 'azure'
  self.instance_id = instance_id
  self.instance_name = site_name
  self.project_name = resource_group
  self.account_id, self.region = parse_azure_app_services_owner_name(owner_name)
end