#!/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}

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

echo "additional_args: ${additional_args}"

rrsa_role_name=$(echo ${additional_args} | jq -r '.alicloudRrsaRoleName')
dataplane_assumed_role_name=$(echo ${additional_args} | jq -r '.dataplaneAssumedRoleName')
crossplane_aws_provider_role_arn=$(echo ${additional_args} | jq -r '.crossplaneAwsProviderRoleArn')
crossplane_aws_provider_name=$(echo ${additional_args} | jq -r '.crossplaneAwsProviderName')
availability_zones=$(echo ${additional_args} | jq -r '.availabilityZones')
cluster_admin_roles=$(echo ${additional_args} | jq -r '.clusterAdminRoles')
image_registry=$(echo ${additional_args} | jq -r '.imageRegistry')
tidb_image_registry=$(echo ${additional_args} | jq -r ".tidbImageRegistry // \"${image_registry}\"")
acr_instance_id=$(echo ${additional_args} | jq -r '.acrInstanceId')
acr_region=$(echo ${additional_args} | jq -r '.acrRegion')
acr_pull_role_arn=$(echo ${additional_args} | jq -r '.acrPullRoleArn')
dataplane_accounts=$(echo ${additional_args} | jq -r '.dataplaneAccounts')
dns_account_id=$(echo ${additional_args} | jq -r '.dnsAccountId')
dns_secret_name=$(echo ${additional_args} | jq -r '.dnsSecretName')
dns_secret_namespace=$(echo ${additional_args} | jq -r '.dnsSecretNamespace')
public_hosted_zone_domain=$(echo ${additional_args} | jq -r '.publicHostedZoneDomain')
resource_name_prefix=$(echo ${additional_args} | jq -r '.resourceNamePrefix // "tidbcloud"')
auth0_audience=$(echo ${additional_args} | jq -r '.auth0Audience')
auth0_domain=$(echo ${additional_args} | jq -r '.auth0Domain')
global_controlplane_ips=$(echo ${additional_args} | jq -r '.globalControlplaneIPs')
regional_controlplane_ips=$(echo ${additional_args} | jq -r '.regionalControlplaneIPs')
o11y_regional_service_ips=$(echo ${additional_args} | jq -r '.o11yRegionalServiceIPs')
clinic_ips=$(echo ${additional_args} | jq -r '.clinicIPs')
bastion_ips=$(echo ${additional_args} | jq -r '.bastionIPs')
# Optional override. When unset, the template value is kept.
admin_node_instance_type=$(echo ${additional_args} | jq -r '.adminNodeInstanceType // ""')
sli_aws_region="us-west-2"
sli_delivery_stream_name="sli-prod-metrics"
sli_delivery_stream_role_arn=$(echo ${additional_args} | jq -r '.sliDeliveryStreamRoleArn')
enable_kong_public_access=$(echo "${additional_args}" | jq -r 'if has("enableKongPublicAccess") then .enableKongPublicAccess else true end')
aliCloudCommonBandwidthPackageIDMap=$(echo ${additional_args} | jq -r '.aliCloudCommonBandwidthPackageIDMap')
kms_account_id=$(echo ${additional_args} | jq -r '.kmsAccountID')
kms_instance_id=$(echo ${additional_args} | jq -r '.kmsInstanceID')

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

# https://stackoverflow.com/questions/4247068/sed-command-with-i-option-failing-on-mac-but-works-on-linux
if [[ "$OSTYPE" == "darwin"* ]]; then
  # Require gnu-sed.
  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

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

mkdir -p "${deploy_dir}"
echo "Prepare manifest files"
cp "${variant_dir}/kustomization_tmpl.yaml" "${deploy_dir}/kustomization.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}/service_account_tmpl.yaml" "${deploy_dir}/service_account.yaml"

mkdir "${deploy_dir}/config"
echo "Prepare config files"
cp "${variant_dir}/config/k8s-addon-templates.yaml" "${deploy_dir}/config/k8s-addon-templates.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/root-config_tmpl.yaml" "${deploy_dir}/config/root-config.yaml"
cp "${variant_dir}/config/o11y-agent-policy-template_tmpl.json" "${deploy_dir}/config/o11y-agent-policy-template.json"


find "${deploy_dir}" -type f -exec ${SED_CMD} -i "s|TMPL_REGION|${region}|g" {} \;
${SED_CMD} -i "s|TMPL_LOGICAL_REGION|${logicalRegionName}|g" "${deploy_dir}/config/root-config.yaml"
${SED_CMD} -i "s|TMPL_RRSA_ROLE_NAME|${rrsa_role_name}|g" "${deploy_dir}/service_account.yaml"
find "${deploy_dir}" -type f -exec ${SED_CMD} -i "s|TPML_IMAGE_REGISTRY|${image_registry}|g" {} \;
find "${deploy_dir}" -type f -exec ${SED_CMD} -i "s|TPML_TIDB_IMAGE_REGISTRY|${tidb_image_registry}|g" {} \;
# replace the auth0 audience and domain
${SED_CMD} -i "s|TMPL_AUTH0_AUDIENCE|${auth0_audience}|g" "${deploy_dir}/config/k8s-dedicated-templates.yaml"
${SED_CMD} -i "s|TMPL_AUTH0_DOMAIN|${auth0_domain}|g" "${deploy_dir}/config/k8s-dedicated-templates.yaml"
# replace the public hosted zone domain and id
${SED_CMD} -i "s|TMPL_PUBLIC_HOSTED_ZONE_DOMAIN|${public_hosted_zone_domain}|g" "${deploy_dir}/config/root-config.yaml"
${SED_CMD} -i "s|TMPL_DNS_MANAGER_ACCOUNT_ID|${dns_account_id}|g" "${deploy_dir}/config/root-config.yaml"
${SED_CMD} -i "s|TMPL_DNS_MANAGER_SECRET_NAME|${dns_secret_name}|g" "${deploy_dir}/config/root-config.yaml"
${SED_CMD} -i "s|TMPL_DNS_MANAGER_SECRET_NS|${dns_secret_namespace}|g" "${deploy_dir}/config/root-config.yaml"
# replace the dataplane role
${SED_CMD} -i "s|TMPL_DATAPLANE_ROLE_NAME|${dataplane_assumed_role_name}|g" "${deploy_dir}/config/root-config.yaml"
${SED_CMD} -i "s|TMPL_RESOURCE_NAME_PREFIX|${resource_name_prefix}|g" "${deploy_dir}/config/root-config.yaml"
# replace awsCrossplaneProviderConfig
AWS_CROSSPLANE_PROVIDER_CONFIG="${crossplane_aws_provider_name}" \
  yq e -i '.awsCrossplaneProviderConfig = strenv(AWS_CROSSPLANE_PROVIDER_CONFIG)' "${deploy_dir}/config/root-config.yaml"
# replace kmsConfig
${SED_CMD} -i "s|TMPL_KMS_ACCOUNT_ID|${kms_account_id}|g" "${deploy_dir}/config/root-config.yaml"
${SED_CMD} -i "s|TMPL_KMS_INSTANCE_ID|${kms_instance_id}|g" "${deploy_dir}/config/root-config.yaml"
# add aliCloudCommonBandwidthPackageIDMap
yq e -i ".internetConfig.aliCloudCommonBandwidthPackageIDMap |= ${aliCloudCommonBandwidthPackageIDMap}" ${deploy_dir}/config/root-config.yaml
# add clusterAdminRoles
yq e -i ".appBoxConfig.clusterAdmins |= $cluster_admin_roles" ${deploy_dir}/config/root-config.yaml
# add inDataAccount: true for dataplane account roles
cluster_admin_count=$(yq e '.appBoxConfig.clusterAdmins | length' ${deploy_dir}/config/root-config.yaml)
if [ "${cluster_admin_count}" -gt 0 ]; then
  for i in $(seq 0 $((cluster_admin_count - 1))); do
    iam_role_arn=$(yq e ".appBoxConfig.clusterAdmins[$i].iamRoleARN" ${deploy_dir}/config/root-config.yaml)
    # Check if iamRoleARN contains any account ID from dataplane_accounts
    if echo "${dataplane_accounts}" | jq -e --arg arn "${iam_role_arn}" '.[] as $acc | $arn | contains($acc) | select(.)' > /dev/null 2>&1; then
      yq e -i ".appBoxConfig.clusterAdmins[$i].inDataAccount = true" ${deploy_dir}/config/root-config.yaml
    fi
  done
fi
# replace ACR parameters
${SED_CMD} -i "s|TMPL_ACR_INSTANCE_ID|${acr_instance_id}|g" "${deploy_dir}/config/root-config.yaml"
${SED_CMD} -i "s|TMPL_ACR_REGION|${acr_region}|g" "${deploy_dir}/config/root-config.yaml"
${SED_CMD} -i "s|TMPL_ACR_PULL_ROLE_ARN|${acr_pull_role_arn}|g" "${deploy_dir}/config/root-config.yaml"

yq e -i ".regionConfig.zones |= $availability_zones" ${deploy_dir}/config/root-config.yaml

root_config=${deploy_dir}/config/root-config.yaml
if [ -n "${admin_node_instance_type}" ]; then
  yq e -i ".appBoxConfig.adminNodeConfig.instanceType = \"${admin_node_instance_type}\"" ${root_config}
fi


mkdir "${deploy_dir}/account"
echo "Prepare account-list.yaml"
# genrate the account list, ptah: account/account-list.yaml
account_list=${deploy_dir}/account/account-list.yaml
cat <<EOF > ${account_list}
accounts:
EOF

for account in $(echo ${dataplane_accounts} | jq -r '.[]'); do
  cat <<EOF >> ${account_list}
  - accountID: "${account}"
    secretName: "alibabacloud-dataplane-secret-${account}"
    secretNamespace: "crossplane-system"
EOF
done

# genrate the controlplane providerconfig, path: config/providerconfig.yaml
# dataplane providerconfig will be created at dataplane-manager start time using account-list.yaml
echo "Prepare providerconfig.yaml"
providerconfig_config=${deploy_dir}/account/providerconfig.yaml
cat <<EOF > ${providerconfig_config}
---
apiVersion: alibabacloud.crossplane.io/v1beta1
kind: ProviderConfig
metadata:
  name: "provider-alicloud"
spec:
  credentials:
    secretRef:
      key: credentials
      name: alibabacloud-secret
      namespace: crossplane-system
    source: Secret
EOF

echo "Prepare dataplane aws-providerconfig.yaml"
aws_providerconfig=${deploy_dir}/account/aws-providerconfig.yaml
cat <<EOF > ${aws_providerconfig}
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: "${crossplane_aws_provider_name}"
spec:
  credentials:
    source: WebIdentity
    webIdentity:
      roleARN: ${crossplane_aws_provider_role_arn}
      tokenConfig:
        fs:
          path: /var/run/secrets/kubernetes.io/serviceaccount/token
        source: Filesystem
EOF

echo "set whitelist ip"
yq e -i ".appBoxConfig.apiserverPublicAccessCidrs |= ${bastion_ips} + ${global_controlplane_ips} + ${regional_controlplane_ips} + ${o11y_regional_service_ips}" \
  ${deploy_dir}/config/root-config.yaml

if $enable_kong_public_access; then
  yq e -i ".appBoxConfig.apiGateway.publicAccessCidrs |= ${global_controlplane_ips} + ${regional_controlplane_ips} + ${clinic_ips}" \
    ${deploy_dir}/config/root-config.yaml
else
  yq e -i "del(.appBoxConfig.apiGateway.publicAccessCidrs)" \
    ${deploy_dir}/config/root-config.yaml
  yq e -i ".appBoxConfig.apiGateway.enablePublicAccess = false" \
    ${deploy_dir}/config/root-config.yaml
fi

# replace the sli config
${SED_CMD} -i "s|TPML_SLI_AWS_REGION|${sli_aws_region}|g" "${deploy_dir}/config/k8s-dedicated-templates.yaml"
${SED_CMD} -i "s|TPML_SLI_FIREHOSE_NAME|${sli_delivery_stream_name}|g" "${deploy_dir}/config/k8s-dedicated-templates.yaml"
${SED_CMD} -i "s|TPML_SLI_FIREHOSE_ROLE_ARN|${sli_delivery_stream_role_arn}|g" "${deploy_dir}/config/k8s-dedicated-templates.yaml"
