#!/usr/bin/env bash

set -x
set -euo pipefail

ROOT=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
source ${ROOT}/../lib.sh

remote_config=${CONFIG_PATH}
local_config=/tmp/base-config.yaml
bucket_name=${remote_config#s3://}
bucket_name=${bucket_name%%/*}
output_bucket_region=$(aws s3api get-bucket-location --bucket=$bucket_name --query="LocationConstraint" \
  --region=us-west-2 --output=text --no-cli-pager)
aws s3 cp ${remote_config} ${local_config}  --region=$output_bucket_region

cloud_provider=$(yq '.cloudProvider' "${local_config}")
region=$(yq '.region' "${local_config}")
logical_region_name=$(yq '.name' "${local_config}")
env=$(yq '.env' "${local_config}")
o11y_eks_remote_output=$(yq '.jobOutput.o11y-eks' "${local_config}")
o11y_eks_local_output=/tmp/o11y-eks-output.yaml
aws s3 cp ${o11y_eks_remote_output} ${o11y_eks_local_output}  --region=$output_bucket_region
cluster_name=$(yq '.cluster_name' "${o11y_eks_local_output}")
account_id=$(yq -r -ojson '.aws.dataplaneAccounts.0' "${local_config}")
resource_owner_tag=$(yq '.jobOptions.resourceOwnerTag' "${local_config}")

# common variables
echo "cloud_provider: $cloud_provider"
echo "region: $region"
echo "logical_region_name: $logical_region_name"
echo "env: $env"
echo "cluster_name: $cluster_name"
echo "account_id: $account_id"

# Create API Gateway VPC Link V2 and REST API
echo "Setting up API Gateway and VPC Link V2..."

vpc_id=$(aws --profile $account_id eks describe-cluster \
  --name $cluster_name \
  --query "cluster.resourcesVpcConfig.vpcId" \
  --output text)
echo "vpc_id: $vpc_id"

# Get all private subnets in the VPC
private_subnet_ids=$(aws --profile $account_id ec2 describe-subnets \
  --region $region \
  --filters "Name=vpc-id,Values=$vpc_id" "Name=tag:Name,Values=*private*" \
  --query "Subnets[].SubnetId" \
  --output text)
echo "private_subnet_ids: $private_subnet_ids"

# Get or create security group for API Gateway VPC Link
sg_name="o11y-${env}-${logical_region_name}-apigw-vpclink"
existing_sg_id=$(aws --profile $account_id ec2 describe-security-groups \
  --region $region \
  --filters "Name=vpc-id,Values=$vpc_id" "Name=group-name,Values=$sg_name" \
  --query "SecurityGroups[0].GroupId" \
  --output text)

if [ "$existing_sg_id" == "None" ] || [ -z "$existing_sg_id" ]; then
  echo "Creating security group for API Gateway VPC Link..."
  sg_id=$(aws --profile $account_id ec2 create-security-group \
    --region $region \
    --group-name "$sg_name" \
    --description "Security group for API Gateway VPC Link to access NLB" \
    --vpc-id $vpc_id \
    --tag-specifications "ResourceType=security-group,Tags=[{Key=tidbcloud-auto-deploy-owner,Value=${resource_owner_tag}}]" \
    --query "GroupId" \
    --output text)

  # Note: AWS automatically creates a default outbound rule allowing all traffic to 0.0.0.0/0
  # This is sufficient for VPC Link to access the NLB

  echo "Created security group: $sg_id"
else
  sg_id=$existing_sg_id
  echo "Security group already exists: $sg_id"
fi

# Wait for ngx-r NLB to be ready and get its information
echo "Waiting for nginx-read NLB to be ready..."
nlb_read_name="ngx-r-$logical_region_name"
nlb_read_state=""
while [ "$nlb_read_state" != "active" ]; do
  nlb_read_state=$(aws --profile "$account_id" elbv2 describe-load-balancers \
    --region $region \
    --names "$nlb_read_name" \
    --query 'LoadBalancers[0].State.Code' \
    --output text 2>/dev/null || echo "provisioning")
  if [ "$nlb_read_state" != "active" ]; then
    echo "nlb_read_state: $nlb_read_state, waiting..."
    sleep 30
  fi
done
echo "nginx-read NLB ready: $nlb_read_name"

nlb_read_arn=$(aws --profile "$account_id" elbv2 describe-load-balancers \
  --region $region \
  --names "$nlb_read_name" \
  --query 'LoadBalancers[0].LoadBalancerArn' \
  --output text)
nlb_read_dns=$(aws --profile "$account_id" elbv2 describe-load-balancers \
  --region $region \
  --names "$nlb_read_name" \
  --query 'LoadBalancers[0].DNSName' \
  --output text)
echo "nlb_read_arn: $nlb_read_arn"
echo "nlb_read_dns: $nlb_read_dns"

# Get ALB ARN & DNS
rs_alb_name="alb-rs-$logical_region_name"
rs_alb_arn=$(aws --profile "$account_id" elbv2 describe-load-balancers \
  --region $region \
  --names "$rs_alb_name" \
  --query 'LoadBalancers[0].LoadBalancerArn' \
  --output text)
rs_alb_dns=$(aws --profile "$account_id" elbv2 describe-load-balancers \
  --region $region \
  --names "$rs_alb_name" \
  --query 'LoadBalancers[0].DNSName' \
  --output text)
echo "rs_alb_arn: $rs_alb_arn"
echo "rs_alb_dns: $rs_alb_dns"

# Create VPC Link V2
vpclink_name="o11y-${env}-${logical_region_name}"
echo "Creating VPC Link V2: $vpclink_name..."

existing_vpclink_id=$(aws --profile $account_id apigatewayv2 get-vpc-links \
  --region $region \
  --query "Items[?Name=='$vpclink_name'].VpcLinkId | [0]" \
  --output text 2>/dev/null || echo "")

if [ -z "$existing_vpclink_id" ] || [ "$existing_vpclink_id" == "None" ]; then
  # Build command with properly formatted subnet IDs
  vpclink_cmd="aws --profile $account_id apigatewayv2 create-vpc-link --region $region --name $vpclink_name"

  # Add each subnet ID as a separate argument
  for subnet_id in $private_subnet_ids; do
    vpclink_cmd="$vpclink_cmd --subnet-ids $subnet_id"
  done

  vpclink_cmd="$vpclink_cmd --security-group-ids $sg_id --tags tidbcloud-auto-deploy-owner=${resource_owner_tag} --query VpcLinkId --output text"

  echo "Executing: $vpclink_cmd"
  vpclink_id=$(eval $vpclink_cmd)

  echo "Created VPC Link V2: $vpclink_id, waiting for it to be available..."

  # Wait for VPC Link to be available
  vpclink_status=""
  max_attempts=60  # 30 minutes timeout (60 attempts * 30 seconds)
  attempt=0
  while [ "$vpclink_status" != "AVAILABLE" ]; do
    vpclink_status=$(aws --profile $account_id apigatewayv2 get-vpc-link \
      --region $region \
      --vpc-link-id $vpclink_id \
      --query "VpcLinkStatus" \
      --output text)

    # Check for failure states
    if [ "$vpclink_status" == "FAILED" ] || [ "$vpclink_status" == "INACTIVE" ]; then
      echo "VPC Link creation failed with status: $vpclink_status"
      exit 1
    fi

    if [ "$vpclink_status" != "AVAILABLE" ]; then
      echo "vpclink_status: $vpclink_status, waiting... (attempt $((attempt + 1))/$max_attempts)"
      sleep 30
      attempt=$((attempt + 1))

      # Check timeout
      if [ $attempt -ge $max_attempts ]; then
        echo "Timeout waiting for VPC Link to become available. Current status: $vpclink_status"
        exit 1
      fi
    fi
  done
  echo "VPC Link V2 is available: $vpclink_id"
else
  vpclink_id=$existing_vpclink_id
  echo "VPC Link V2 already exists: $vpclink_id"
fi

# Create REST API Gateway
api_name="o11y-${env}-${logical_region_name}"
echo "Creating REST API Gateway: $api_name..."

existing_api_id=$(aws --profile $account_id apigateway get-rest-apis \
  --region $region \
  --query "items[?name=='$api_name'].id" \
  --output text 2>/dev/null || echo "")

if [ -z "$existing_api_id" ] || [ "$existing_api_id" == "None" ]; then
  api_id=$(aws --profile $account_id apigateway create-rest-api \
    --region $region \
    --name "$api_name" \
    --description "API Gateway for O11Y region $logical_region_name" \
    --endpoint-configuration types=REGIONAL \
    --tags tidbcloud-auto-deploy-owner=${resource_owner_tag} \
    --query "id" \
    --output text)
  echo "Created REST API: $api_id"

  # Get root resource id
  root_resource_id=$(aws --profile $account_id apigateway get-resources \
    --region $region \
    --rest-api-id $api_id \
    --query "items[?path=='/'].id" \
    --output text)
  echo "root_resource_id: $root_resource_id"

  # Create /ds resource
  ds_resource_id=$(aws --profile $account_id apigateway create-resource \
    --region $region \
    --rest-api-id $api_id \
    --parent-id $root_resource_id \
    --path-part "ds" \
    --query "id" \
    --output text)
  echo "Created /ds resource: $ds_resource_id"

  # Create proxy resource /ds/{proxy+}
  ds_proxy_resource_id=$(aws --profile $account_id apigateway create-resource \
    --region $region \
    --rest-api-id $api_id \
    --parent-id $ds_resource_id \
    --path-part "{proxy+}" \
    --query "id" \
    --output text)
  echo "Created /ds proxy resource: $ds_proxy_resource_id"

  # Create ANY method for the /ds proxy resource with AWS_IAM authorization
  aws --profile $account_id apigateway put-method \
    --region $region \
    --rest-api-id $api_id \
    --resource-id $ds_proxy_resource_id \
    --http-method ANY \
    --authorization-type AWS_IAM \
    --request-parameters "method.request.path.proxy=true" \
    --no-cli-pager
  echo "Created ANY method for /ds proxy resource"

  # Create VPC Link integration for the /ds proxy resource
  aws --profile $account_id apigateway put-integration \
    --region $region \
    --rest-api-id $api_id \
    --resource-id $ds_proxy_resource_id \
    --http-method ANY \
    --type HTTP_PROXY \
    --integration-http-method ANY \
    --uri "http://${nlb_read_dns}/{proxy}" \
    --connection-type VPC_LINK \
    --connection-id $vpclink_id \
    --integration-target ${nlb_read_arn} \
    --request-parameters "integration.request.path.proxy=method.request.path.proxy" \
    --no-cli-pager
  echo "Created VPC Link integration for /ds"

  # Create /rs resource
  rs_resource_id=$(aws --profile $account_id apigateway create-resource \
    --region $region \
    --rest-api-id $api_id \
    --parent-id $root_resource_id \
    --path-part "rs" \
    --query "id" \
    --output text)
  echo "Created /rs resource: $rs_resource_id"

  # Create proxy resource /rs/{proxy+}
  rs_proxy_resource_id=$(aws --profile $account_id apigateway create-resource \
    --region $region \
    --rest-api-id $api_id \
    --parent-id $rs_resource_id \
    --path-part "{proxy+}" \
    --query "id" \
    --output text)
  echo "Created /rs proxy resource: $rs_proxy_resource_id"

  # Create ANY method for the /rs proxy resource with AWS_IAM authorization
  aws --profile $account_id apigateway put-method \
    --region $region \
    --rest-api-id $api_id \
    --resource-id $rs_proxy_resource_id \
    --http-method ANY \
    --authorization-type AWS_IAM \
    --request-parameters "method.request.path.proxy=true" \
    --no-cli-pager
  echo "Created ANY method for /rs proxy resource"

  # Create VPC Link integration for the /rs proxy resource
  aws --profile $account_id apigateway put-integration \
    --region $region \
    --rest-api-id $api_id \
    --resource-id $rs_proxy_resource_id \
    --http-method ANY \
    --type HTTP_PROXY \
    --integration-http-method ANY \
    --uri "http://${rs_alb_dns}/{proxy}" \
    --connection-type VPC_LINK \
    --connection-id $vpclink_id \
    --integration-target ${rs_alb_arn} \
    --request-parameters "integration.request.path.proxy=method.request.path.proxy" \
    --no-cli-pager
  echo "Created VPC Link integration for /rs"

  # Create deployment and stage
  deployment_id=$(aws --profile $account_id apigateway create-deployment \
    --region $region \
    --rest-api-id $api_id \
    --stage-name tidbcloud \
    --stage-description "Production stage for tidbcloud" \
    --description "Initial deployment" \
    --query "id" \
    --output text)
  echo "Created deployment and stage 'tidbcloud': $deployment_id"

  api_endpoint="https://${api_id}.execute-api.${region}.amazonaws.com/tidbcloud"
  echo "API Gateway endpoint: $api_endpoint"
else
  api_id=$existing_api_id
  echo "REST API Gateway already exists: $api_id"
  api_endpoint="https://${api_id}.execute-api.${region}.amazonaws.com/tidbcloud"
  echo "API Gateway endpoint: $api_endpoint"
fi

echo "API Gateway and VPC Link V2 setup completed successfully!"
