#!/usr/bin/env bash
set -xeou pipefail
o11yAgentJobName=${1:-"o11y-agent"}

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

argocd_repo=tidbcloud/app-delivery
region=$(yq '.region' "${local_config}")
logicalRegionName=$(yq '.name' "${local_config}")
env=$(yq '.env' "${local_config}")
cloud=$(yq '.cloudProvider' "${local_config}")
cluster=$(yq '.k8s.name' "${local_config}")
jobId=$(yq '.jobId' "${local_config}")
output=$(yq '.outputPath' "${local_config}")
imageRegistry=$(yq '.imageRegistry' "${local_config}")
controlplane_account=$(yq '.aws.controlplaneAccount' "${local_config}")
regionalControlplaneIPs=$(yq -ojson '.k8s.publicIps | map(. + "/32")' "$local_config") # eg: ["52.79.68.176/32", "3.35.39.51/32"]

availabilityZones=$(yq -ojson '.jobOptions.dataplaneManager.availabilityZones | split(",")' "${local_config}") # eg: ["us-west-2a", "us-west-2b", "us-west-2c"]
dataplaneAccounts=$(yq -ojson '.aws.dataplaneAccounts' "${local_config}") # eg: ["123456789012", "234567890123"]
auth0Audience=$(yq '.jobOptions.dataplaneManager.auth0Audience' "${local_config}") # eg: prod-proxy-service
auth0Domain=$(yq '.jobOptions.dataplaneManager.auth0Domain' "${local_config}") # eg: tidb.auth0.com
globalControlplaneIPs=$(yq -ojson '.jobOptions.dataplaneManager.globalControlplaneIPs' "${local_config}") # eg: ["44.231.162.131/32", "100.20.198.224/32"]
o11yRegionalServiceIPs=$(yq -ojson '.jobOptions.dataplaneManager.o11yRegionalServiceIPs' "${local_config}") # eg: ["1.2.3.5/32", "3.4.5.6/32"]
clinicIPs=$(yq -ojson '.jobOptions.dataplaneManager.clinicIPs' "${local_config}") # eg: ["3.5.7.7/32"]
bastionIPs=$(yq -ojson '.jobOptions.dataplaneManager.bastionIPs' "${local_config}") # eg: ["6.4.6.4/32"]

publicHostedZoneDomain=$(yq '.jobOptions.dataplaneManager.publicHostedZoneDomain' "${local_config}") # eg: tidbcloud.com
o11yRegionalServiceEndpoint=$(yq '.jobOptions.dataplaneManager.o11yRegionalServiceEndpoint' "${local_config}") # eg: https://o11y.tidbcloud.com
is_byoc=$(yq '.jobOptions.isByoc // "false"' "${local_config}")
pcaArn=$(yq '.jobOptions.ng-service.pcaArn' "${local_config}")
tidbImageRegistry=$(yq ".jobOptions.dataplaneManager.tidbImageRegistry // \"${imageRegistry}\"" "${local_config}")

if $is_byoc; then
  byocDataplaneAccount=$(yq '.aws.dataplaneAccounts.0' "${local_config}")
  publicHostedZoneID=$(aws --profile $byocDataplaneAccount route53 list-hosted-zones \
    --query "HostedZones[?Name=='$publicHostedZoneDomain.'].Id" \
    --output text)
else
  publicHostedZoneID=$(aws route53 list-hosted-zones \
    --query "HostedZones[?Name=='$publicHostedZoneDomain.'].Id" \
    --output text)
fi
publicHostedZoneID="${publicHostedZoneID#/hostedzone/}"
echo "publicHostedZoneID: $publicHostedZoneID"

remote_iam_config=$(yq '.jobOutput.iam' "${local_config}")
local_iam_config=/tmp/iam-config.yaml
aws s3 cp ${remote_iam_config} ${local_iam_config} --region=$output_bucket_region
awsIrsaRoleArn=$(yq '.dataplane_manager.roleArn' "${local_iam_config}")
defaultAwsDp4DrsRole=$(yq '.jobOptions.dataplaneManager.dataplaneAssumedRole // "tidbcloud-dataplane-manager-assumed-role"' "${local_config}")
eksServiceRoleName=$(yq '.jobOptions.dataplaneManager.eksServiceRoleName // "tidbcloud-eks-service-role"' "${local_config}")
nodeRoleName=$(yq '.jobOptions.dataplaneManager.nodeRoleName // "tidbcloud-eks-node-role"' "${local_config}")
sliDeliveryStreamRoleArn=$(yq '.jobOptions.dataplaneManager.sliDeliveryStreamRoleArn // ""' "${local_config}")

dataplaneManagerDataplaneRoleArns=$(echo "$dataplaneAccounts" | jq -c 'map("arn:aws:iam::\(.):role/'"$defaultAwsDp4DrsRole"'")')
authorizedSubjects=$(yq -ojson -e ".jobOptions.dataplaneManager.authorizedSubjects + \
  [\"$awsIrsaRoleArn\"] + $dataplaneManagerDataplaneRoleArns" \
  "${local_config}")

byoc="null"
dnsAccountId="${controlplane_account}"
dnsManagerRoleArn="${awsIrsaRoleArn}"
enableKongPlugin=false
if $is_byoc; then
    dnsAccountId="$byocDataplaneAccount"
    dnsManagerRoleArn="arn:aws:iam::${dnsAccountId}:role/${defaultAwsDp4DrsRole}"
    enableKongPlugin=true
    vpc_id=$(aws eks describe-cluster \
        --name $cluster \
        --query "cluster.resourcesVpcConfig.vpcId" \
        --output text)
        echo "found vpc: $vpc_id"
    cluster_sg=$(aws eks describe-cluster \
        --name $cluster \
        --query "cluster.resourcesVpcConfig.clusterSecurityGroupId" \
        --output text)
    private_subnets=$(aws ec2 describe-subnets \
        --filters "Name=vpc-id,Values=$vpc_id" \
        --query "Subnets[?Tags[?Key=='kubernetes.io/role/internal-elb']].SubnetId" \
        --output json)
    byoc=$(cat <<EOF
{
  "nodeRoleName": "tidbcloud-eks-node-role",
  "privateLink": {
    "controlPlaneVPCID": "$vpc_id",
    "controlPlaneSubnetIDs": $private_subnets,
    "controlPlaneSecurityGroupIDs": [
      "$cluster_sg"
    ]
  }
}
EOF
)
fi

additionalArgs=$(cat <<EOF
{
  "awsIrsaRoleArn": "$awsIrsaRoleArn",
  "defaultAwsDp4DrsRole": "$defaultAwsDp4DrsRole",
  "eksServiceRoleName": "$eksServiceRoleName",
  "nodeRoleName": "$nodeRoleName",
  "availabilityZones": $availabilityZones,
  "imageRegistry": "$imageRegistry",
  "tidbImageRegistry": "$tidbImageRegistry",
  "dataplaneAccounts": $dataplaneAccounts,
  "auth0Audience": "$auth0Audience",
  "auth0Domain": "$auth0Domain",
  "globalControlplaneIPs": $globalControlplaneIPs,
  "regionalControlplaneIPs": $regionalControlplaneIPs,
  "o11yRegionalServiceIPs": $o11yRegionalServiceIPs,
  "clinicIPs": $clinicIPs,
  "bastionIPs": $bastionIPs,
  "authorizedSubjects": $authorizedSubjects,
  "publicHostedZoneDomain": "$publicHostedZoneDomain",
  "publicHostedZoneID": "$publicHostedZoneID",
  "pcaArn": "$pcaArn",
  "enableKongPlugin": "${enableKongPlugin}",
  "dnsAccountId": "${dnsAccountId}",
  "dnsManagerRoleArn": "${dnsManagerRoleArn}",
  "sliDeliveryStreamRoleArn": "${sliDeliveryStreamRoleArn}",
  "byoc": $byoc
}
EOF
)
echo "additionalArgs: $additionalArgs"

# Deploy application services by invoking deploy-new-region action in $argocd_repo
common_params="-f cloud=${cloud} -f region=${region} -f env=${env} -f cluster=${cluster} -f jobId=${jobId} -f logicalRegionName=${logicalRegionName}"
export GH_REPO="${argocd_repo}"
gh workflow run deploy-new-region-next-gen-dataplane-manager.yaml ${common_params} -f additionalArgs="${additionalArgs}"

# Wait services ready
declare -A services
services["deploy/dataplane-controller"]="false"
services["deploy/dataplane-server"]="false"
namespace="dataplane-manager"
wait_for_services_ready services namespace
if [[ $? -eq 1 ]]; then
    echo "Services are not ready"
    exit 1
fi
