#!/usr/bin/env bash
set -euo pipefail

usage() {
  cat >&2 <<'EOF'
Usage:
  deploy-new-region.sh <region> <env> <cloud> <logicalRegionName> <additionalArgs.json>

Examples:
  deploy-new-region.sh us-east-2 prod aws us-east-2-ng args.json
  deploy-new-region.sh ap-southeast-2 staging alicloud ap-southeast-2-ng args.json
  deploy-new-region.sh eastus2 dev azure eastus2-ng args.json
EOF
}

if [ "$#" -ne 5 ]; then
  usage
  exit 1
fi

region=$1
env=$2
cloud=$3
logical_region_name=$4
json_file_path=$5

if ! command -v jq >/dev/null 2>&1; then
  echo "Error: jq is required" >&2
  exit 1
fi

if [ ! -f "${json_file_path}" ]; then
  echo "Error: additionalArgs file does not exist: ${json_file_path}" >&2
  exit 1
fi

case "${cloud}" in
  aws)
    provider_alias=aws
    vendor=aws
    ;;
  alicloud)
    provider_alias=ali
    vendor=alicloud
    ;;
  azure)
    provider_alias=azure
    vendor=azure
    ;;
  *)
    echo "Error: unsupported cloud '${cloud}', expected aws, alicloud, or azure" >&2
    exit 1
    ;;
esac

case "${env}:${cloud}" in
  dev:alicloud)
    deploy_env="alicloud-dev-${logical_region_name}"
    ;;
  dev:azure)
    deploy_env="dev-azure-${logical_region_name}"
    ;;
  *)
    deploy_env="${env}-${provider_alias}-${logical_region_name}"
    ;;
esac

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

if [ ! -d "${variant_dir}" ]; then
  echo "Error: variant directory does not exist: ${variant_dir}" >&2
  exit 1
fi

if [ -e "${deploy_dir}" ]; then
  echo "Error: new region deploy directory already exists: ${deploy_dir}" >&2
  exit 1
fi

json_payload=$(jq -c 'if type == "string" then fromjson else . end' "${json_file_path}")

json_required() {
  local name=$1
  local query=$2
  local value
  if ! value=$(jq -er "${query} // empty" <<<"${json_payload}" 2>/dev/null); then
    echo "Error: missing required additionalArgs.${name}" >&2
    exit 1
  fi
  if [ -z "${value}" ]; then
    echo "Error: missing required additionalArgs.${name}" >&2
    exit 1
  fi
  printf '%s' "${value}"
}

json_optional() {
  local query=$1
  local default=$2
  local value
  value=$(jq -er "${query} // empty" <<<"${json_payload}" 2>/dev/null || true)
  if [ -z "${value}" ]; then
    printf '%s' "${default}"
  else
    printf '%s' "${value}"
  fi
}

json_optional_json() {
  local query=$1
  jq -c "if ${query} == null then empty else ${query} end" <<<"${json_payload}" 2>/dev/null || true
}

normalize_hour_start_time() {
  local value=$1
  if ! [[ "${value}" =~ ^[0-9]+$ ]]; then
    echo "Error: additionalArgs.startTime must be a Unix timestamp in seconds" >&2
    exit 1
  fi
  local value_seconds=$((10#${value}))
  printf '%s' "$((value_seconds - value_seconds % 3600))"
}

replace_token() {
  local token=$1
  local value=$2
  local escaped
  escaped=$(printf '%s' "${value}" | sed -e 's/[|&]/\\&/g')
  find "${deploy_dir}" -type f -exec sed -i.bak "s|${token}|${escaped}|g" {} \; -exec rm -f "{}.bak" \;
}

image_registry=$(json_required imageRegistry '.imageRegistry')
image_tag=$(json_required imageTag '.imageTag')
bucket=$(json_required bucket '.bucket')
start_time=$(normalize_hour_start_time "$(json_required startTime '.startTime')")

task_interval=$(json_optional '.taskInterval' '15')
delay_minutes=$(json_optional '.delayMinutes' '5')
if [ "${env}" = "prod" ]; then
  default_reporter_interval=30
  default_maintenance_enable=true
else
  default_reporter_interval=60
  default_maintenance_enable=false
fi
reporter_interval=$(json_optional '.reporterInterval' "${default_reporter_interval}")
maintenance_enable=$(json_optional '.maintenanceEnable' "${default_maintenance_enable}")
maintenance_enable_delete=$(json_optional '.maintenanceEnableDelete' 'true')
delete_retention_days=$(json_optional '.deleteRetentionDays' '90')
delete_before_timestamp=$(json_optional '.deleteBeforeTimestamp' '0')
maintenance_enable_vacuum=$(json_optional '.maintenanceEnableVacuum' 'true')
vacuum_retention_hours=$(json_optional '.vacuumRetentionHours' '168')
vacuum_dry_run=$(json_optional '.vacuumDryRun' 'false')
aws_reporter_region=$(json_optional '.awsReporterRegion' 'us-west-2')

plan=$(json_optional '.plan' '')
if [ -n "${plan}" ]; then
  plan_line="  plan: \"${plan}\""
else
  plan_line=""
fi

enable_pprof=$(json_optional '.enablePprof' '')
if [ -n "${enable_pprof}" ]; then
  enable_pprof_line="enablePprof: ${enable_pprof}"
else
  enable_pprof_line=""
fi

feature_gate_filter=$(json_optional_json '.featureGateFilter')
if [ -n "${feature_gate_filter}" ]; then
  feature_gate_filter_line="  featureGateFilter: ${feature_gate_filter}"
else
  feature_gate_filter_line=""
fi

metering_role_line=""
storage_role_line=""
irsa_role_arn=""
aws_reporter_role_arn=""
azure_workload_identity_client_id=""
azure_storage_account_name=""
bucket_endpoint=""
ram_secret_key=$(json_optional '.ramSecretKey' 'metering-ram-key')
delta_scheme=s3

case "${cloud}" in
  aws)
    irsa_role_arn=$(json_required irsaRoleArn '.irsaRoleArn')
    metering_role_arn=$(json_optional '.meteringRoleArn' '')
    if [ -n "${metering_role_arn}" ]; then
      metering_role_line="  roleArn: \"${metering_role_arn}\""
      storage_role_line="    AWS_IAM_ROLE_ARN: \"${metering_role_arn}\""
    fi
    ;;
  alicloud)
    aws_reporter_role_arn=$(json_required awsReporterRoleArn '.awsReporterRoleArn')
    bucket_endpoint=$(json_optional '.bucketEndpoint' "https://oss-${region}.aliyuncs.com")
    ;;
  azure)
    delta_scheme=azure
    azure_workload_identity_client_id=$(json_required azureWorkloadIdentityClientID '.azureWorkloadIdentityClientID')
    azure_storage_account_name=$(json_required azureStorageAccountName '.azureStorageAccountName')
    bucket_endpoint=$(json_required bucketEndpoint '.bucketEndpoint')
    aws_reporter_role_arn=$(json_required awsReporterRoleArn '.awsReporterRoleArn')
    ;;
esac

mkdir -p "${deploy_dir}"
cp -R "${variant_dir}/." "${deploy_dir}/"

image="${image_registry}/tidbcloud/nextgen-metering-server:${image_tag}"
delta_table_path="${delta_scheme}://${bucket}/metering/result/metering-data"

replace_token TMPL_BUCKET_ENDPOINT "${bucket_endpoint}"
replace_token TMPL_DELTA_TABLE_PATH "${delta_table_path}"
replace_token TMPL_BUCKET "${bucket}"
replace_token TMPL_ENV "${env}"
replace_token TMPL_VENDOR "${vendor}"
replace_token TMPL_REGION "${region}"
replace_token TMPL_START_TIME "${start_time}"
replace_token TMPL_TASK_INTERVAL "${task_interval}"
replace_token TMPL_DELAY_MINUTES "${delay_minutes}"
replace_token TMPL_REPORTER_INTERVAL "${reporter_interval}"
replace_token TMPL_MAINTENANCE_ENABLE_DELETE "${maintenance_enable_delete}"
replace_token TMPL_MAINTENANCE_ENABLE_VACUUM "${maintenance_enable_vacuum}"
replace_token TMPL_MAINTENANCE_ENABLE "${maintenance_enable}"
replace_token TMPL_DELETE_RETENTION_DAYS "${delete_retention_days}"
replace_token TMPL_DELETE_BEFORE_TIMESTAMP "${delete_before_timestamp}"
replace_token TMPL_VACUUM_RETENTION_HOURS "${vacuum_retention_hours}"
replace_token TMPL_VACUUM_DRY_RUN "${vacuum_dry_run}"
replace_token TMPL_PLAN_LINE "${plan_line}"
replace_token TMPL_ENABLE_PPROF_LINE "${enable_pprof_line}"
replace_token TMPL_FEATURE_GATE_FILTER_LINE "${feature_gate_filter_line}"
replace_token TMPL_METERING_ROLE_LINE "${metering_role_line}"
replace_token TMPL_STORAGE_ROLE_LINE "${storage_role_line}"
replace_token TMPL_IRSA_ROLE_ARN "${irsa_role_arn}"
replace_token TMPL_AWS_REPORTER_REGION "${aws_reporter_region}"
replace_token TMPL_AWS_REPORTER_ROLE_ARN "${aws_reporter_role_arn}"
replace_token TMPL_RAM_SECRET_KEY "${ram_secret_key}"
replace_token TMPL_AZURE_WORKLOAD_IDENTITY_CLIENT_ID "${azure_workload_identity_client_id}"
replace_token TMPL_AZURE_STORAGE_ACCOUNT_NAME "${azure_storage_account_name}"
replace_token TMPL_IMAGE "${image}"

if grep -R "TMPL_" "${deploy_dir}" >/dev/null; then
  echo "Error: generated files contain unreplaced placeholders" >&2
  grep -R "TMPL_" "${deploy_dir}" >&2
  exit 1
fi

echo "Generated nextgen-metering-server region overlay: ${deploy_dir}"
