set -euo pipefail
region=$1

# execute curl to retry different IPs
function curl_retry_diff_ip() {
  local url=$1
  shift 1

  # 提取协议
  local proto=${url%%://*}
  # 提取 domain:port
  local hostport=${url#*://}
  local hostport=${hostport%%/*}

  # 判断是否包含端口
  local domain=""
  local port=""
  if [[ "$hostport" == *:* ]]; then
    domain=${hostport%%:*}
    port=${hostport##*:}
  else
    domain=$hostport
    # 根据协议设置默认端口
    if [[ "$proto" == "https" ]]; then
      port=443
    else
      port=80
    fi
  fi

  local ips=$(dig +short $domain)
  local curl_options="--retry 0 --connect-timeout 5"
  set +e
  for ip in $ips; do
    curl --resolve "$domain:$port:$ip" "$url" $curl_options "$@"
    if [[ $? -eq 0 ]]; then
      return 0
    fi
  done
  set -e
  return 1
}

timestamp="$(date +%s)000"
curl_retry="--connect-timeout 5 --max-time 10 --retry 10 --no-keepalive -v"
location_url="https://b0.p.awsstatic.com/locations/1.0/aws/current/locations.json?timestamp=$timestamp"
# locations=$(curl "$location_url" $curl_retry -sL --compressed -XGET)
locations=$(curl_retry_diff_ip "$location_url" -sL --compressed -XGET )
region_name=$(echo $locations | jq -r "to_entries[] | select(.value.code == \"$region\") | .value.name")
if [[ -z "$region_name" ]]; then
  printf "\e[31mRegion $region not found\e[0m\n"
  exit 1
fi
echo "region_name: $region_name"

# check regional service
echo "Check AWS supported regional services"
# all_regional_services=$(curl 'https://api.regional-table.region-services.aws.a2z.com/index.json' $curl_retry -sGL)
all_regional_services=$(curl_retry_diff_ip 'https://api.regional-table.region-services.aws.a2z.com/index.json' -sGL)
required_services=(
  "AWS Security Hub"
  "AWS Secrets Manager"
  "Amazon Simple Queue Service (SQS)"
  "AWS Key Management Service"
  "Elastic Load Balancing"
  "AWS Config"
  "AWS CloudTrail"
  "Amazon Virtual Private Cloud (VPC)"
  "Amazon Simple Notification Service (SNS)"
  "Amazon Simple Storage Service (S3)"
  "Amazon GuardDuty"
  "Amazon Elastic Kubernetes Service (EKS)"
  "Amazon Elastic Container Registry (ECR)"
  "Amazon Elastic Compute Cloud (EC2)"
  "Amazon CloudWatch"
  "AWS Glue"
  "Amazon Relational Database Service (RDS)"
  "AWS CloudFormation"
  "Amazon CloudFront"
  "Amazon DynamoDB"
  "Amazon Location Service"
  "AWS Lambda"
  "Amazon Kinesis Data Streams"
  "Amazon Route 53"
)

required_services_json=$(printf '%s\n' "${required_services[@]}" | jq -R . | jq -s .)
missed_services=$(echo "$all_regional_services" | jq -r \
  --argjson required_services "$required_services_json" \
  --arg region "$region" \
  '(
    [ .prices[] 
      | select(.attributes."aws:region" == $region) 
      | .attributes."aws:serviceName"
    ]
  ) as $existing
  | $required_services
  | map(select(. as $s | $existing | index($s) | not))
  | join(",")
')
if [[ -z "$missed_services" ]]; then
  printf "\e[32mAll services are supported\e[0m\n"
else
  printf "\e[31mMissed services: $missed_services\e[0m\n"
fi

# check io2
echo "Check io2 support"
# ebs_prices=$(curl 'https://b0.p.awsstatic.com/pricing/2.0/meteredUnitMaps/ec2/USD/current/ebs.json' $curl_retry -sGL --compressed)
ebs_prices=$(curl_retry_diff_ip 'https://b0.p.awsstatic.com/pricing/2.0/meteredUnitMaps/ec2/USD/current/ebs.json' -sGL --compressed)
io2_storage_price=$(echo $ebs_prices | jq -r ".regions.\"$region_name\".\"Storage Provisioned IOPS io2 GB month\".price // \"\"")
if [[ -n "$io2_storage_price" ]]; then
  printf "\e[32mIO2 is supported\e[0m\n"
else
  printf "\e[33mIO2 is not supported\e[0m\n"
fi

# check ec2 instance types
echo "Check EC2 instance types"
encoded_region_name=$(jq -nr --arg p "$region_name" '$p | @uri')
ec2_prices_url="https://b0.p.awsstatic.com/pricing/2.0/meteredUnitMaps/ec2/USD/current/ec2-ondemand-without-sec-sel/$encoded_region_name/Linux/index.json?timestamp=$timestamp"
# echo "ec2_prices_url: $ec2_prices_url"
# ec2_prices=$(curl "$ec2_prices_url" $curl_retry -sGL --compressed)
ec2_prices=$(curl_retry_diff_ip "$ec2_prices_url" -sGL --compressed)

instances=$(
  cat <<EOF
- type: m6i
  required: true
- type: m6g
  required: true
- type: c6i
  required: true
- type: c6g
  required: true
- type: r6i
  required: true
- type: r6g
  required: true
- type: c5
  required: false
- type: m5
  required: false
- type: r5
  required: false
- type: r5b
  required: false
EOF
)
count=$(echo "$instances" | yq -r '. | length')
for ((i = 0; i < $count; i++)); do
  instance_type=$(echo "$instances" | yq -r ".[$i].type")
  required=$(echo "$instances" | yq -r ".[$i].required")
  instance_types=$(echo "$ec2_prices" | jq -r --arg region_name "$region_name" \
    --arg prefix "$instance_type." \
    '.regions[$region_name] | to_entries
      | map(select(.value["Instance Type"] | startswith($prefix)))
      | sort_by(.value["vCPU"] | tonumber)
      | map((.value["Instance Type"] + "            ")[0:12])
      | join(" ")')
  if [[ "$instance_types" == "" ]]; then
    if [[ "$required" == "true" ]]; then
      printf "\e[31m%-3s is NOT supported\e[0m\n" "$instance_type"
    else
      printf "\e[33m%-3s is optional\e[0m\n" "$instance_type"
    fi
  else
    printf "\e[32m%-3s supported\e[0m: $instance_types\n" "$instance_type"
  fi
done
