#!/bin/bash

set -euo pipefail

WORKSPACE=$(unset CDPATH && cd $(dirname "${BASH_SOURCE[0]}") && pwd)
CHARTS="$WORKSPACE/../charts"
source "$WORKSPACE/common.sh"
source "$WORKSPACE/../lib/lib.sh"

VENDOR=${1:-"aws"}
ENV=${2:-"dev"}
REGION=${3:-""}
LOGICAL_REGION=${4:-"$REGION"}
BYOC_ENABLED=${5:-"false"}

# only use ops server with BYOC enabled.
if [[ "${MANAGED_BY_OPS_SERVER:-false}" == "true" && "$BYOC_ENABLED" == "true" ]]; then
  : "${AUTH0_CLIENT_ID:?AUTH0_CLIENT_ID is required for managed ops deploys}"
  : "${AUTH0_CLIENT_SECRET:?AUTH0_CLIENT_SECRET is required for managed ops deploys}"
  bash "$WORKSPACE/deploy-with-ops.sh" "$VENDOR" "$ENV" "$REGION" "$LOGICAL_REGION" "$BYOC_ENABLED"
  exit 0
fi

# 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>"
  exit 1
fi

# metrics-stats is used to collect metrics status from VM clusters and write it to deltalake.
if [[ "$BYOC_ENABLED" != "true" && "$ENV" == "prod" ]]; then
    echo "start upgrading metrics-stats"
    metrics_stats_env="$WORKSPACE/metrics-stats/envs/${ENV}-${VENDOR}-${LOGICAL_REGION}"
    if [[ -d "$metrics_stats_env" ]]; then
      metrics_stats_rendered="$(mktemp -d "${TMPDIR:-/tmp}/metrics-stats-XXXXXX")"
      render_metrics_stats_manifests \
        "$metrics_stats_env" \
        "$(resolve_image_tag_file "$WORKSPACE/metrics-stats" "$ENV" "$VENDOR" "$LOGICAL_REGION")" \
        "$metrics_stats_rendered"
      kubectl apply -f "$metrics_stats_rendered"
      rm -rf "$metrics_stats_rendered"
    else
      echo "metrics-stats env dir not found: $metrics_stats_env, skip"
    fi
    echo "end upgrading metrics-stats"
fi

# diagnosis query is used by query slowlogs, sqlstatement, topsql, conprof, and keyviz
echo "start upgrading diagnosis query"
helm_adopt_apply diagnosis-query observability "$CHARTS/diagnosis-query" \
  -f "$WORKSPACE/diagnosis-query/envs/${ENV}-${VENDOR}-${LOGICAL_REGION}/values.yaml" \
  -f "$(resolve_image_tag_file "$WORKSPACE/diagnosis-query" "$ENV" "$VENDOR" "$LOGICAL_REGION")"
echo "end upgrading diagnosis query"

# diagnosis-deltalake is used to process slowlogs data.
echo "start upgrading o11y diagnosis deltalake"
helm_adopt_apply o11ydiagnosis-deltalake observability "$CHARTS/o11ydiagnosis-deltalake" \
  -f "$WORKSPACE/o11ydiagnosis-deltalake/envs/${ENV}-${VENDOR}-${LOGICAL_REGION}/values.yaml" \
  -f "$(resolve_image_tag_file "$WORKSPACE/o11ydiagnosis-deltalake" "$ENV" "$VENDOR" "$LOGICAL_REGION")"
echo "end upgrading o11y diagnosis deltalake"

# logstats is used to process raw logs data
if [[ "$BYOC_ENABLED" != "true" ]]; then
    echo "start upgrading o11y diagnosis logstats"

    helm_adopt_apply o11ydiagnosis-logstats observability "$CHARTS/o11ydiagnosis-logstats" \
      -f "$WORKSPACE/o11ydiagnosis-logstats/envs/${ENV}-${VENDOR}-${LOGICAL_REGION}/values.yaml" \
      -f "$(resolve_image_tag_file "$WORKSPACE/o11ydiagnosis-logstats" "$ENV" "$VENDOR" "$LOGICAL_REGION")"
    echo "end upgrading o11y diagnosis logstats"
fi

# deltalake ops server is used to write deltalake for logstats.
if [[ "$BYOC_ENABLED" != "true" ]]; then
    helm_adopt_apply deltalake-ops-server observability "$CHARTS/deltalake-ops-server" -f "$WORKSPACE/deltalake-ops-server/envs/${ENV}-${VENDOR}-${LOGICAL_REGION}/values.yaml"
    echo "end upgrading deltalake ops server"
fi

# auth server is used to get aws credentials and o11yid for other services. It needs only one instance for each vendor.
if [[ "$VENDOR" == "aws" && "$LOGICAL_REGION" == "us-west-2" && "$ENV" == "prod" ]]; then
    echo "start upgrading auth-server"

    # auth-server JWT secret is managed by CI/CD (GitHub Actions -> K8s Secret).
    # This avoids committing plaintext JWT into Helm templates/values.
    kubectl create namespace observability-client --dry-run=client -o yaml | kubectl apply -f -
    if [ -z "${SECRET_AUTHSERVER_JWT:-}" ]; then
      echo "Error: SECRET_AUTHSERVER_JWT is empty; auth-server-jwt Secret not updated."
      echo "Set GitHub secret O11Y_AUTHSERVER_JWT_SECRET and re-run drhouse-cd."
      exit 1
    fi

    kubectl -n observability-client create secret generic auth-server-jwt \
      --from-literal=JWT_SECRET="${SECRET_AUTHSERVER_JWT}" \
      --dry-run=client -o yaml | kubectl apply -f -

    helm upgrade -i --create-namespace --debug -n observability-client -f $WORKSPACE/auth-server/envs/${ENV}-${VENDOR}-${LOGICAL_REGION}/values.yaml auth-server $CHARTS/auth-server
    echo "end upgrading auth-server"
fi

if [[ "$BYOC_ENABLED" != "true" && "$ENV" == "prod" && ("$VENDOR" == "aws" || "$VENDOR" == "gcp" || "$VENDOR" == "alicloud") ]]; then
    echo "start upgrading metering-server"

    if kubectl get configmap meteringconfig -n observability &> /dev/null; then
        kubectl label configmap meteringconfig -n observability app.kubernetes.io/managed-by=Helm --overwrite
        kubectl annotate configmap meteringconfig -n observability meta.helm.sh/release-name=metering-server meta.helm.sh/release-namespace=observability --overwrite
    fi

    echo "delete Legacy metering-server"
    if kubectl get svc regional-metering-service -n observability &> /dev/null; then
        kubectl delete statefulset metering-server -n observability
        kubectl delete svc regional-metering-service -n observability
        kubectl delete pvc data-metering-server-0   -n observability
    fi

    # Replace SECRET values from environment variables
    # Function to handle cross-platform sed compatibility with proper escaping
    sed_inplace() {
        local pattern="$1"
        local replacement="$2"
        local file="$3"

        # Escape special characters in the replacement string for sed
        # Escape & and \ which have special meaning in sed replacement
        local escaped_replacement=$(printf '%s\n' "$replacement" | sed 's/[[\.*^$()+?{|]/\\&/g; s/&/\\&/g')

        if [[ "$OSTYPE" == "darwin"* ]]; then
            sed -i '' "s|${pattern}|${escaped_replacement}|g" "$file"
        else
            sed -i "s|${pattern}|${escaped_replacement}|g" "$file"
        fi
    }

    if [ -n "${SECRET_CLIENT_ID:-}" ]; then
        sed_inplace "SECRET_CLIENT_ID" "${SECRET_CLIENT_ID}" "$WORKSPACE/metering-server/envs/${ENV}-${VENDOR}-${LOGICAL_REGION}/values.yaml"
    fi

    if [ -n "${SECRET_CLIENT_SECRET:-}" ]; then
        sed_inplace "SECRET_CLIENT_SECRET" "${SECRET_CLIENT_SECRET}" "$WORKSPACE/metering-server/envs/${ENV}-${VENDOR}-${LOGICAL_REGION}/values.yaml"
    fi

    if [ -n "${SECRET_DSN:-}" ]; then
        sed_inplace "SECRET_DSN" "${SECRET_DSN}" "$WORKSPACE/metering-server/envs/${ENV}-${VENDOR}-${LOGICAL_REGION}/values.yaml"
    fi

    helm upgrade -i --create-namespace --debug -n observability -f $WORKSPACE/metering-server/envs/${ENV}-${VENDOR}-${LOGICAL_REGION}/values.yaml metering-server $CHARTS/metering-server
    echo "end upgrading metering-server"
fi
