#!/bin/bash

set -euo pipefail

vendor=${1:-}
env=${2:-}
region=${3:-}
logical_region=${4:-}

# throw error if any of the arguments are not set
if [ -z "$vendor" ] || [ -z "$env" ] || [ -z "$region" ] || [ -z "$logical_region" ]; then
  echo "Error: Missing required arguments."
  echo "Usage: $0 <vendor> <env> <region> <logical_region>"
  echo ""
  echo "Parameters:"
  echo "  vendor         - Cloud vendor (aws, gcp, azure, alicloud)"
  echo "  env            - Environment (dev, staging, prod)"
  echo "  region         - Physical region name"
  echo "  logical_region - Logical region name to remove"
  echo ""
  echo "This script will:"
  echo "  - Remove the logical region from the vendor configuration"
  echo "  - Clean up all routes pointing to the logical region"
  echo "  - Remove associated Karma, Grafana, and Promxy configurations"
  exit 1
fi
echo "region: $region env: $env vendor: $vendor logical_region: $logical_region"

ROOT=$(cd $(dirname ${BASH_SOURCE[0]}) && pwd)

echo "unregister region from globalserver configmap"
global_file_path="$ROOT/manifests/${env}/meta.json"
global_configmap_path="$ROOT/manifests/${env}/configmap.yaml"

if [[ "$env" == "dev" && ! -f "$global_file_path" ]]; then
  echo "Dev global observability is offline; no global registration remains to remove."
  exit 0
fi

if [[ ! -f "$global_file_path" ]]; then
  echo "Error: Global configuration file does not exist: $global_file_path" >&2
  exit 1
fi

# Check if the region exists in the vendors list
if jq -e ".vendors.${vendor} | any(.region == \"${region}\")" $global_file_path > /dev/null; then
  # Check how many routers are in this region
  router_count=$(jq -r ".vendors.${vendor}[] | select(.region == \"${region}\") | .routers | length" $global_file_path)

  if [[ $router_count -gt 1 ]]; then
    # 1. More than one router exists, just remove the specific router
    echo "Multiple routers found for region '${region}'. Removing router with logicalRegionName '${logical_region}'."
    jq ".vendors.${vendor}[] |= if .region == \"${region}\" then .routers |= map(select(.logicalRegionName != \"${logical_region}\")) else . end" $global_file_path > $global_file_path.tmp && mv $global_file_path.tmp $global_file_path
  else
    # 2. This is the last router, check if the removed logical region was the last router in the region
    last_router_logical_region=$(jq -r ".vendors.${vendor}[] | select(.region == \"${region}\") | .routers[0].logicalRegionName" $global_file_path)
    if [[ "$last_router_logical_region" == "$logical_region" ]]; then
      echo "Last router for region '${region}'. Removing entire region."
      jq "del(.vendors.${vendor}[] | select(.region == \"${region}\"))" $global_file_path > $global_file_path.tmp && mv $global_file_path.tmp $global_file_path
    else
      echo "Last router for region '${region}', but logical region '${logical_region}' does not match the last router's logical region '${last_router_logical_region}'."
    fi
  fi
else
  echo "Region '${region}' not found in vendor '${vendor}' configuration."
fi

# Clean up routes related to the logical region being removed
echo "Cleaning up routes for logical region '${logical_region}'"
route_key="${vendor}-${region}"

# Check if routes exist for this route key
if jq -e ".routes.\"${route_key}\"" $global_file_path > /dev/null; then
  echo "Found routes for route key '${route_key}'"

  # Get all route patterns that point to this logical region
  routes_to_remove=$(jq -r ".routes.\"${route_key}\" | to_entries[] | select(.value == \"${logical_region}\") | .key" $global_file_path)

  if [ -n "$routes_to_remove" ]; then
    echo "Removing routes pointing to logical region '${logical_region}':"
    while IFS= read -r route_pattern; do
      if [ -n "$route_pattern" ]; then
        echo "  - Removing route: ${route_pattern} -> ${logical_region}"
        jq "del(.routes.\"${route_key}\".\"${route_pattern}\")" $global_file_path > $global_file_path.tmp && mv $global_file_path.tmp $global_file_path
      fi
    done <<< "$routes_to_remove"

    # Check if the route key is now empty and remove it if so
    remaining_routes=$(jq -r ".routes.\"${route_key}\" | length" $global_file_path 2>/dev/null || echo "0")
    if [ "$remaining_routes" = "0" ]; then
      echo "Route key '${route_key}' is now empty, removing it"
      jq "del(.routes.\"${route_key}\")" $global_file_path > $global_file_path.tmp && mv $global_file_path.tmp $global_file_path
    fi
  else
    echo "No routes found pointing to logical region '${logical_region}' in route key '${route_key}'"
  fi
else
  echo "No routes found for route key '${route_key}'"
fi

if [[ $env != "staging" ]]; then
  echo "remove region from karma configMap.rawConfig.alertmanager.servers if exists"
  KARMA_VALUES_PATH="$ROOT/karma/values-${env}.yaml"
  AM_SERVER_NAME="${vendor}-${logical_region}"
  AM_SELF_MONITORING_SERVER_NAME="o11y-selfmon-${vendor}-${logical_region}"

  # remove AM_SERVER_NAME from configMap.rawConfig.alertmanager.servers
  yq -i "del(.configMap.rawConfig.alertmanager.servers[] | select(.name == \"${AM_SERVER_NAME}\"))" $KARMA_VALUES_PATH

  yq -i "del(.configMap.rawConfig.alertmanager.servers[] | select(.name == \"${AM_SELF_MONITORING_SERVER_NAME}\"))" $KARMA_VALUES_PATH
fi

echo "remove region from grafana datasources if exists"
PROME_STACK_PATH="$ROOT/../infra-v2/kube-prometheus-stack/envs/${env}/global-aws-us-west-2.yaml"
PROM_DATASOURCE_NAME="Prometheus-regional-${logical_region}"
LOKI_DATASOURCE_NAME="Loki-regional-${logical_region}"

# Match the datasource naming convention in register-new-region.sh
if [[ $vendor == "alicloud" ]]; then
  PROM_DATASOURCE_NAME="Prometheus-regional-alicloud-${logical_region}"
  LOKI_DATASOURCE_NAME="Loki-regional-alicloud-${logical_region}"
fi

# A datasource removed from additionalDataSources must also be listed in
# deleteDatasources, otherwise Grafana keeps the stale entry in its database.
for DS_NAME in "$PROM_DATASOURCE_NAME" "$LOKI_DATASOURCE_NAME"; do
  if yq -e ".grafana.additionalDataSources[] | select(.name == \"${DS_NAME}\")" $PROME_STACK_PATH > /dev/null 2>&1; then
    yq -i "del(.grafana.additionalDataSources[] | select(.name == \"${DS_NAME}\"))" $PROME_STACK_PATH
  fi
  if ! yq -e ".grafana.deleteDatasources[] | select(.name == \"${DS_NAME}\")" $PROME_STACK_PATH > /dev/null 2>&1; then
    echo "Appending datasource '${DS_NAME}' to grafana deleteDatasources"
    yq -i ".grafana.deleteDatasources += [{\"name\":\"${DS_NAME}\",\"orgId\":1}]" $PROME_STACK_PATH
  fi
done

echo "Removing logical region from promxy config"
PROMXY_VALUES_PATH="$ROOT/promxy/values-${env}.yaml"

EXPECTED_K8S_CLUSTER="${vendor}-${logical_region}"

# Remove the server group with the matching k8s_cluster label
# Note: We only check k8s_cluster label, not target, because BYOC regions share the same Kong proxy
# and matching by target could accidentally remove the wrong region
if yq -e ".config.promxy.server_groups[] | select(.labels.k8s_cluster == \"${EXPECTED_K8S_CLUSTER}\")" $PROMXY_VALUES_PATH > /dev/null 2>&1; then
  echo "Removing server group with k8s_cluster '${EXPECTED_K8S_CLUSTER}' from promxy config"
  yq -i ".config.promxy.server_groups = (.config.promxy.server_groups | map(select(.labels.k8s_cluster != \"${EXPECTED_K8S_CLUSTER}\")))" $PROMXY_VALUES_PATH
else
  echo "Logical region '${EXPECTED_K8S_CLUSTER}' not found in promxy config"
fi

echo "Region unregistration completed successfully!"
echo ""
echo "Cleanup summary:"
echo "  - Removed logical region '${logical_region}' from vendor '${vendor}' region '${region}'"
echo "  - Cleaned up all routes pointing to logical region '${logical_region}'"
echo "  - Removed Karma alertmanager servers"
echo "  - Removed Grafana datasources"
echo "  - Removed Promxy server groups"
echo ""
echo "Updated files:"
echo "  - $global_file_path"
echo "  - $global_configmap_path"
if [[ $env != "staging" ]]; then
  echo "  - $KARMA_VALUES_PATH"
fi
echo "  - $PROME_STACK_PATH"
echo "  - $PROMXY_VALUES_PATH"
