#!/usr/bin/env bash
set -euo pipefail
# When changing this script, remember to modify the corresponding github action
region=${1}
env=${2}
cloud=${3}
json_file_path=${4}
logicalRegionName=${5}

if [ "${cloud}" != "azure" ]; then
  echo "Unsupported cloud provider: ${cloud}"
  exit 1
fi

additional_args=$(jq -r '.' "${json_file_path}")

echo "additional_args: ${additional_args}"

aws_irsa_role_arn=$(echo "${additional_args}" | jq -r '.awsIrsaRoleArn // ""')
aws_crossplane_provider_config=$(echo "${aws_irsa_role_arn}" | awk -F: '{print $5}')
availability_zones=$(echo "${additional_args}" | jq -c '.availabilityZones // []')
image_registry=$(echo "${additional_args}" | jq -r '.imageRegistry // ""')
tidb_image_registry=$(echo "${additional_args}" | jq -r ".tidbImageRegistry // \"${image_registry}\"")
control_plane_subscription_id=$(echo "${additional_args}" | jq -r '.controlPlaneSubscriptionID // ""')
azure_workload_identity_client_id=$(echo "${additional_args}" | jq -r '.azureWorkloadIdentityClientID // ""')
azure_workload_identity_tenant_id=$(echo "${additional_args}" | jq -r '.azureWorkloadIdentityTenantID // ""')
dataplane_tenant_id=$(echo "${additional_args}" | jq -r ".dataplaneTenantID // \"${azure_workload_identity_tenant_id}\"")
hosted_zone_tenant_id=$(echo "${additional_args}" | jq -r ".hostedZoneTenantID // \"${azure_workload_identity_tenant_id}\"")
hosted_zone_subscription_id=$(echo "${additional_args}" | jq -r ".hostedZoneSubscriptionID // \"${control_plane_subscription_id}\"")
hosted_zone_resource_group=$(echo "${additional_args}" | jq -r '.hostedZoneResourceGroup // ""')
public_hosted_zone_domain=$(echo "${additional_args}" | jq -r '.publicHostedZoneDomain // ""')
global_controlplane_ips=$(echo "${additional_args}" | jq -c '.globalControlplaneIPs // []')
regional_controlplane_ips=$(echo "${additional_args}" | jq -c '.regionalControlplaneIPs // []')
o11y_regional_service_ips=$(echo "${additional_args}" | jq -c '.o11yRegionalServiceIPs // []')
clinic_ips=$(echo "${additional_args}" | jq -c '.clinicIPs // []')
bastion_ips=$(echo "${additional_args}" | jq -c '.bastionIPs // []')
enable_kong_public_access=$(echo "${additional_args}" | jq -r 'if has("enableKongPublicAccess") then .enableKongPublicAccess else true end')
enable_kong_plugin=$(echo ${additional_args} | jq -r '.enableKongPlugin // true')
resource_name_prefix=$(echo "${additional_args}" | jq -r '.resourceNamePrefix // "tidbcloud"')
service_role_name=$(echo "${additional_args}" | jq -r '.serviceRoleName // .eksServiceRoleName // "tidbcloud-eks-service-role"')
pca_arn=$(echo "${additional_args}" | jq -r '.pcaArn // ""')
byoc=$(echo "${additional_args}" | jq -c '.byoc // null')
dataplane_accounts=$(echo "${additional_args}" | jq -c '.dataplaneAccounts // []')
auth0_audience=$(echo "${additional_args}" | jq -r '.auth0Audience // "dev-proxy-service"')
auth0_domain=$(echo "${additional_args}" | jq -r '.auth0Domain // "tidb-dev.us.auth0.com"')
sli_aws_region=$(echo "${additional_args}" | jq -r '.sliAwsRegion // "us-west-2"')
sli_firehose_name=$(echo "${additional_args}" | jq -r '.sliFirehoseName // "sli-dev-metrics"')
sli_firehose_role_arn=$(echo "${additional_args}" | jq -r '.sliFirehoseRoleArn // "arn:aws:iam::552185537300:role/sli-cross-account-role"')
control_plane_crossplane_provider_config=$(echo "${additional_args}" | jq -r '.controlPlaneCrossplaneProviderConfig // .controlPlaneSubscriptionID // ""')
acr_resource_group=$(echo "${additional_args}" | jq -r '.acrResourceGroup // "container_registry_rg"')
admin_group_object_ids=$(echo "${additional_args}" | jq -c '.adminGroupObjectIDs // empty')
node_config=$(echo "${additional_args}" | jq -c '.nodeConfig // empty')
admin_node_config=$(echo "${additional_args}" | jq -c '.adminNodeConfig // empty')
worker_node_config=$(echo "${additional_args}" | jq -c '.workerNodeConfig // empty')
node_pools=$(echo "${additional_args}" | jq -c '.nodePools // empty')

if [ "${availability_zones}" = "[]" ]; then
  availability_zones=$(printf '["%s-1","%s-2","%s-3"]' "${region}" "${region}" "${region}")
fi

ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
variant_dir="${ROOT}/variants/${env}-azure"
deploy_dir="${ROOT}/envs/${cloud}-${env}-${logicalRegionName}"

if [ ! -d "${variant_dir}" ]; then
  echo "Variant directory not found: ${variant_dir}"
  exit 1
fi

if [ -e "${deploy_dir}" ]; then
  echo "New region deploy directory already exist"
  exit 1
fi

mkdir -p "${deploy_dir}/config" "${deploy_dir}/account"
cp "${variant_dir}/kustomization_tmpl.yaml" "${deploy_dir}/kustomization.yaml"
cp "${variant_dir}/controller-deployment_tmpl.yaml" "${deploy_dir}/controller-deployment.yaml"
cp "${variant_dir}/server-deployment_tmpl.yaml" "${deploy_dir}/server-deployment.yaml"
cp "${variant_dir}/service_account_tmpl.yaml" "${deploy_dir}/service_account.yaml"
cp "${variant_dir}/controller-version_tmpl.yaml" "${deploy_dir}/controller-version.yaml"
cp "${variant_dir}/server-version_tmpl.yaml" "${deploy_dir}/server-version.yaml"
cp "${variant_dir}/config/root-config_tmpl.yaml" "${deploy_dir}/config/root-config.yaml"
cp "${variant_dir}/config/k8s-dedicated-templates_tmpl.yaml" "${deploy_dir}/config/k8s-dedicated-templates.yaml"
cp "${variant_dir}/config/k8s-dp-templates_tmpl.yaml" "${deploy_dir}/config/k8s-dp-templates.yaml"
cp "${variant_dir}/config/k8s-infra-templates_tmpl.yaml" "${deploy_dir}/config/k8s-infra-templates.yaml"
cp "${variant_dir}/config/k8s-addon-templates.yaml" "${deploy_dir}/config/k8s-addon-templates.yaml"
cp "${variant_dir}/config/cert-manager-policy-template.json" "${deploy_dir}/config/cert-manager-policy-template.json"
cp "${variant_dir}/config/o11y-agent-policy-template.json" "${deploy_dir}/config/o11y-agent-policy-template.json"

if [[ "$OSTYPE" == "darwin"* ]]; then
  if ! [ -x "$(command -v gsed)" ]; then
    echo "Error: 'gsed' is not installed." >&2
    echo "If you are using Homebrew, install with 'brew install gnu-sed'." >&2
    exit 1
  fi
  SED_CMD=gsed
else
  SED_CMD=sed
fi

disable_proxy_protocol=false

# Apply BYOC-specific template if BYOC is enabled
if [ "${byoc}" != null ]; then
  echo "Apply BYOC-specific configurations"

  disable_proxy_protocol=true

  # Merge k8s-dedicated-templates with BYOC-specific configurations
  if [ -f "${variant_dir}/config/k8s-dedicated-templates_byoc_tmpl.yaml" ]; then
    # Use yq to deep merge BYOC overlay into base template (array element at index 0)
    yq eval-all 'select(fileIndex == 0) | .[0] as $base |
      load("'"${variant_dir}/config/k8s-dedicated-templates_byoc_tmpl.yaml"'") | .[0] as $overlay |
      [$base * $overlay]
    ' \
      "${deploy_dir}/config/k8s-dedicated-templates.yaml" \
      > "${deploy_dir}/config/k8s-dedicated-templates.yaml.tmp"
    mv "${deploy_dir}/config/k8s-dedicated-templates.yaml.tmp" "${deploy_dir}/config/k8s-dedicated-templates.yaml"
  else
    echo "Warning: BYOC template not found at ${variant_dir}/config/k8s-dedicated-templates_byoc_tmpl.yaml"
  fi

  # Enable dataplane-exporter only for BYOC regions.
  if [ -f "${variant_dir}/config/k8s-infra-templates_dataplane-exporter_tmpl.yaml" ]; then
    yq eval-all 'select(fileIndex == 0) | .[0] as $base |
      load("'"${variant_dir}/config/k8s-infra-templates_dataplane-exporter_tmpl.yaml"'") | .[0] as $overlay |
      [$base * $overlay]
    ' \
      "${deploy_dir}/config/k8s-infra-templates.yaml" \
      > "${deploy_dir}/config/k8s-infra-templates.yaml.tmp"
    mv "${deploy_dir}/config/k8s-infra-templates.yaml.tmp" "${deploy_dir}/config/k8s-infra-templates.yaml"
  else
    echo "Warning: dataplane-exporter template not found at ${variant_dir}/config/k8s-infra-templates_dataplane-exporter_tmpl.yaml"
  fi
fi

find "${deploy_dir}" -type f -exec ${SED_CMD} -i "s|${env}-westus3-ng|${env}-${logicalRegionName}|g" {} \;
find "${deploy_dir}" -type f -exec ${SED_CMD} -i "s|westus3-ng|${logicalRegionName}|g" {} \;
find "${deploy_dir}" -type f -exec ${SED_CMD} -i "s|westus3|${region}|g" {} \;
find "${deploy_dir}" -type f -exec ${SED_CMD} -i "s|TMPL_LOGICAL_REGION|${logicalRegionName}|g" {} \;
find "${deploy_dir}" -type f -exec ${SED_CMD} -i "s|TMPL_REGION|${region}|g" {} \;

find "${deploy_dir}/config" -type f -exec ${SED_CMD} -i "s|tidbclouddev.azurecr.io|${tidb_image_registry}|g" {} \;
find "${deploy_dir}/config" -type f -exec ${SED_CMD} -i "s|TPML_TIDB_IMAGE_REGISTRY|${tidb_image_registry}|g" {} \;
${SED_CMD} -i "s|tidbclouddev.azurecr.io|${image_registry}|g" "${deploy_dir}/controller-version.yaml"
${SED_CMD} -i "s|tidbclouddev.azurecr.io|${image_registry}|g" "${deploy_dir}/server-version.yaml"

ROOT_CONFIG="${deploy_dir}/config/root-config.yaml"
K8S_DEDICATED_TEMPLATES="${deploy_dir}/config/k8s-dedicated-templates.yaml"
K8S_DP_TEMPLATES="${deploy_dir}/config/k8s-dp-templates.yaml"
SERVICE_ACCOUNT="${deploy_dir}/service_account.yaml"
CONTROLLER_DEPLOYMENT="${deploy_dir}/controller-deployment.yaml"
SERVER_DEPLOYMENT="${deploy_dir}/server-deployment.yaml"

${SED_CMD} -i "s|TMPL_AUTH0_AUDIENCE|${auth0_audience}|g" "${K8S_DEDICATED_TEMPLATES}"
${SED_CMD} -i "s|TMPL_AUTH0_DOMAIN|${auth0_domain}|g" "${K8S_DEDICATED_TEMPLATES}"
${SED_CMD} -i "s|TMPL_SLI_AWS_REGION|${sli_aws_region}|g" "${K8S_DEDICATED_TEMPLATES}"
${SED_CMD} -i "s|TMPL_SLI_FIREHOSE_NAME|${sli_firehose_name}|g" "${K8S_DEDICATED_TEMPLATES}"
${SED_CMD} -i "s|TMPL_SLI_FIREHOSE_ROLE_ARN|${sli_firehose_role_arn}|g" "${K8S_DEDICATED_TEMPLATES}"
${SED_CMD} -i "s|TMPL_DISABLE_PROXY_PROTOCOL|${disable_proxy_protocol}|g" "${ROOT_CONFIG}"

if $enable_kong_plugin; then
  echo "enable kong plugin"
  yq -i '.[].clusterGateway.helmValues.plugins.configMaps = [{"pluginName": "auth-server", "name":"kong-plugin-auth-server"}]' ${K8S_DEDICATED_TEMPLATES}

  # Set ingress plugins based on BYOC status
  if [ "${byoc}" != null ]; then
    # BYOC: enable auth-server and audit-kong plugins
    yq -i '.[].dataflowAgent.helmValues.ingress = {"enabled": true, "plugins": "auth-server,audit-kong"}' ${K8S_DP_TEMPLATES}
  else
    # Non-BYOC: set basic auth-server plugin only
    yq -i '.[].dataflowAgent.helmValues.ingress = {"enabled": true, "plugins": "auth-server"}' ${K8S_DP_TEMPLATES}
  fi
fi

AZURE_WI_CLIENT_ID="${azure_workload_identity_client_id}" \
AZURE_WI_TENANT_ID="${dataplane_tenant_id}" \
AWS_IRSA_ROLE_ARN="${aws_irsa_role_arn}" \
CP_SUB="${control_plane_subscription_id}" \
HZ_RG="${hosted_zone_resource_group}" \
PUBLIC_DOMAIN="${public_hosted_zone_domain}" \
SERVICE_ROLE_NAME="${service_role_name}" \
RESOURCE_NAME_PREFIX="${resource_name_prefix}" \
yq e -i '
  .metadata.annotations."azure.workload.identity/client-id" = strenv(AZURE_WI_CLIENT_ID) |
  .metadata.annotations."azure.workload.identity/tenant-id" = strenv(AZURE_WI_TENANT_ID)
' "${SERVICE_ACCOUNT}"

AWS_IRSA_ROLE_ARN="${aws_irsa_role_arn}" yq e -i '
  (.spec.template.spec.containers[] | select(.name == "controller").env[] | select(.name == "AWS_ROLE_ARN").value) = strenv(AWS_IRSA_ROLE_ARN)
' "${CONTROLLER_DEPLOYMENT}"

AWS_IRSA_ROLE_ARN="${aws_irsa_role_arn}" yq e -i '
  (.spec.template.spec.containers[] | select(.name == "server").env[] | select(.name == "AWS_ROLE_ARN").value) = strenv(AWS_IRSA_ROLE_ARN)
' "${SERVER_DEPLOYMENT}"

HZ_SUB="${hosted_zone_subscription_id}" \
AZURE_WI_CLIENT_ID="${azure_workload_identity_client_id}" \
HZ_TENANT_ID="${hosted_zone_tenant_id}" \
HZ_RG="${hosted_zone_resource_group}" \
PUBLIC_DOMAIN="${public_hosted_zone_domain}" \
SERVICE_ROLE_NAME="${service_role_name}" \
RESOURCE_NAME_PREFIX="${resource_name_prefix}" \
CROSSPLANE_PROVIDER_CONFIG="${control_plane_crossplane_provider_config}" \
AWS_CROSSPLANE_PROVIDER_CONFIG="${aws_crossplane_provider_config}" \
ACR_RESOURCE_GROUP="${acr_resource_group}" \
LOGICAL_REGION="${logicalRegionName}" \
REGION_NAME="${region}" \
yq e -i '
  .regionConfig.logicalRegionName = strenv(LOGICAL_REGION) |
  .regionConfig.name = strenv(REGION_NAME) |
  .dnsProviderConfig.azureDNSZone.subscriptionID = strenv(HZ_SUB) |
  .dnsProviderConfig.azureDNSZone.tenantID = strenv(HZ_TENANT_ID) |
  .dnsProviderConfig.azureDNSZone.clientID = strenv(AZURE_WI_CLIENT_ID) |
  .dnsProviderConfig.azureDNSZone.resourceGroup = strenv(HZ_RG) |
  .dnsProviderConfig.azureDNSZone.domain = strenv(PUBLIC_DOMAIN) |
  .appBoxConfig.serviceRoleName = strenv(SERVICE_ROLE_NAME) |
  .resourceNamePrefix = strenv(RESOURCE_NAME_PREFIX) |
  .controlPlaneCrossplaneProviderConfig = strenv(CROSSPLANE_PROVIDER_CONFIG) |
  .awsCrossplaneProviderConfig = strenv(AWS_CROSSPLANE_PROVIDER_CONFIG) |
  .acrResourceGroup = strenv(ACR_RESOURCE_GROUP)
' "${ROOT_CONFIG}"

if [ -n "${node_config}" ]; then
  yq e -i '.appBoxConfig.nodeConfig = '"${node_config}" "${ROOT_CONFIG}"
fi

if [ -n "${admin_node_config}" ]; then
  yq e -i '.appBoxConfig.adminNodeConfig = '"${admin_node_config}" "${ROOT_CONFIG}"
fi

if [ -n "${worker_node_config}" ]; then
  yq e -i '.appBoxConfig.workerNodeConfig = '"${worker_node_config}" "${ROOT_CONFIG}"
fi

if [ -n "${node_pools}" ]; then
  yq e -i '.appBoxConfig.nodePools = '"${node_pools}" "${ROOT_CONFIG}"
fi

if [ -n "${admin_group_object_ids}" ]; then
  yq e -i '.appBoxConfig.adminGroupObjectIDs = '"${admin_group_object_ids}" "${ROOT_CONFIG}"
fi

yq e -i '.regionConfig.zones = '"${availability_zones}" "${ROOT_CONFIG}"
yq e -i '.appBoxConfig.apiserverPublicAccessCidrs = (((.appBoxConfig.apiserverPublicAccessCidrs // []) + '"${bastion_ips}"' + '"${global_controlplane_ips}"' + '"${regional_controlplane_ips}"' + '"${o11y_regional_service_ips}"') | unique)' "${ROOT_CONFIG}"
if $enable_kong_public_access; then
  yq e -i '.appBoxConfig.apiGateway.publicAccessCidrs = (((.appBoxConfig.apiGateway.publicAccessCidrs // []) + '"${global_controlplane_ips}"' + '"${regional_controlplane_ips}"' + '"${clinic_ips}"') | unique)' "${ROOT_CONFIG}"
else
  yq e -i 'del(.appBoxConfig.apiGateway.publicAccessCidrs)' "${ROOT_CONFIG}"
  yq e -i '.appBoxConfig.apiGateway.enablePublicAccess = false' "${ROOT_CONFIG}"
fi

if [ -n "${pca_arn}" ]; then
  PCA_ARN="${pca_arn}" yq e -i '.appBoxConfig.pcaConfig.caIdentifier = strenv(PCA_ARN)' "${ROOT_CONFIG}"
fi

if [ "${byoc}" != "null" ]; then
  yq e -i ". += {\"byoc\": ${byoc}}" "${ROOT_CONFIG}"
fi

account_list="${deploy_dir}/account/account-list.yaml"
providerconfig_file="${deploy_dir}/account/providerconfig.yaml"

cat <<EOF > "${account_list}"
accounts:
EOF

if [ -n "${aws_crossplane_provider_config}" ]; then
cat <<EOF > "${providerconfig_file}"
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: "${aws_crossplane_provider_config}"
spec:
  credentials:
    source: WebIdentity
    webIdentity:
      roleARN: ${aws_irsa_role_arn}
      tokenConfig:
        fs:
          path: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
        source: Filesystem
EOF
fi

cat <<EOF >> "${providerconfig_file}"
---
apiVersion: azure.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: "${control_plane_subscription_id}"
spec:
  credentials:
    source: OIDCTokenFile
  subscriptionID: ${control_plane_subscription_id}
  clientID: ${azure_workload_identity_client_id}
  tenantID: ${azure_workload_identity_tenant_id}
EOF

echo "${dataplane_accounts}" | jq -c '.[]' | while read -r account; do
  subscription_id=$(echo "${account}" | jq -r '.subscriptionID')
  bucket_resource_group=$(echo "${account}" | jq -r '.bucketResourceGroup // ""')

  cat <<EOF >> "${account_list}"
  - subscriptionID: ${subscription_id}
    bucketResourceGroup: ${bucket_resource_group}
EOF

  if [ "${subscription_id}" != "${control_plane_subscription_id}" ]; then
    cat <<EOF >> "${providerconfig_file}"
---
apiVersion: azure.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: "${subscription_id}"
spec:
  credentials:
    source: OIDCTokenFile
  subscriptionID: ${subscription_id}
  clientID: ${azure_workload_identity_client_id}
  tenantID: ${dataplane_tenant_id}
EOF
  fi
done
