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

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
source "$ROOT/deployments/lib/lib.sh"

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

mkdir -p "$tmpdir/chart"
cat >"$tmpdir/chart/Chart.yaml" <<'YAML'
apiVersion: v2
name: alertmanager-regional
version: 1.2.3
YAML

version="$(read_chart_version "$tmpdir/chart")"
if [[ "$version" != "1.2.3" ]]; then
  echo "expected chart version 1.2.3, got $version"
  exit 1
fi

cat >"$tmpdir/values.yaml" <<'YAML'
replicaCount: 1
YAML

payload="$(build_helmrelease_payload "alertmanager-regional" "observability" "alertmanager-regional" "$tmpdir/values.yaml" "1.2.3")"
echo "$payload" | jq -e '.name == "alertmanager-regional"' >/dev/null
echo "$payload" | jq -e '.component == "alertmanager-regional"' >/dev/null
echo "$payload" | jq -e '.config.version == "1.2.3"' >/dev/null
echo "$payload" | jq -e '.config | has("suspend") | not' >/dev/null
echo "$payload" | jq -e '.config | has("sourceRef") | not' >/dev/null
echo "$payload" | jq -e '.config | has("expectedDigest") | not' >/dev/null

if echo "$payload" | jq -e 'has("expected_digest") or (.config | has("expected_digest"))' >/dev/null 2>&1; then
  echo "payload should not contain snake_case expected_digest"
  exit 1
fi

fake_helm_bin="$(mktemp -d)"
trap 'rm -rf "$tmpdir" "$fake_helm_bin"' EXIT
cat >"$fake_helm_bin/helm" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
if [[ "${1:-}" == "version" ]]; then
  printf '%s\n' 'version.BuildInfo{Version:"v4.0.5"}'
  exit 0
fi
printf '%s\n' "$*" >"${TEST_HELM_LOG:?}"
EOF
chmod +x "$fake_helm_bin/helm"

TEST_HELM_LOG="$tmpdir/helm.log" PATH="$fake_helm_bin:$PATH" \
  helm_adopt_apply example-release observability "$tmpdir/chart" --wait -f "$tmpdir/values.yaml"

if [[ "$(cat "$tmpdir/helm.log")" != 'upgrade --install --take-ownership --server-side=true --force-conflicts --create-namespace --debug -n observability example-release '"$tmpdir"'/chart --wait -f '"$tmpdir"'/values.yaml' ]]; then
  echo "helm_adopt_apply should use helm upgrade --install with adoption flags"
  cat "$tmpdir/helm.log"
  exit 1
fi

old_helm_bin="$(mktemp -d)"
trap 'rm -rf "$tmpdir" "$fake_helm_bin" "$old_helm_bin"' EXIT
cat >"$old_helm_bin/helm" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
if [[ "${1:-}" == "version" ]]; then
  printf '%s\n' 'version.BuildInfo{Version:"v4.0.4"}'
  exit 0
fi
printf '%s\n' "$*" >"${TEST_HELM_OLD_LOG:?}"
EOF
chmod +x "$old_helm_bin/helm"

HELM_UPGRADE_INSTALL_SERVER_SIDE_READY=""
if TEST_HELM_OLD_LOG="$tmpdir/helm-old.log" PATH="$old_helm_bin:$PATH" \
  helm_adopt_apply old-release observability "$tmpdir/chart" -f "$tmpdir/values.yaml" 2>"$tmpdir/helm-old.err"; then
  echo "helm_adopt_apply should reject Helm versions older than v4.0.5"
  exit 1
fi
if [[ -f "$tmpdir/helm-old.log" ]]; then
  echo "helm_adopt_apply should fail before invoking helm upgrade on unsupported versions"
  cat "$tmpdir/helm-old.log"
  exit 1
fi
grep -q 'Helm v4.0.5 or newer is required' "$tmpdir/helm-old.err"

# --- bootstrap/self-adoption helpers ---

# Test resolve_ops_server_url with ingress host in values file
cat >"$tmpdir/ops-values.yaml" <<'YAML'
ingress:
  enabled: true
  hosts:
    - host: www.rs.us-west-2-byoc-0303.aws.observability-dev.pingcap.cloud
      paths:
        - path: /ops/api/v1/
          pathType: Prefix
          port: 8180
flux:
  repo:
    registry: "227896186585.dkr.ecr.us-west-2.amazonaws.com"
    provider: aws
YAML

resolved_url="$(resolve_ops_server_url "$tmpdir/ops-values.yaml")"
if [[ "$resolved_url" != "http://www.rs.us-west-2-byoc-0303.aws.observability-dev.pingcap.cloud" ]]; then
  echo "resolve_ops_server_url: expected http://www.rs.us-west-2-byoc-0303.aws.observability-dev.pingcap.cloud, got $resolved_url"
  exit 1
fi

cat >"$tmpdir/ops-values-tls.yaml" <<'YAML'
ingress:
  enabled: true
  hosts:
    - host: ops.example.com
  tls:
    - hosts:
        - ops.example.com
      secretName: ops-example-tls
YAML

resolved_tls_url="$(resolve_ops_server_url "$tmpdir/ops-values-tls.yaml")"
if [[ "$resolved_tls_url" != "https://ops.example.com" ]]; then
  echo "resolve_ops_server_url: expected https://ops.example.com, got $resolved_tls_url"
  exit 1
fi

# Test resolve_ops_server_url returns empty when ingress host is null/missing
cat >"$tmpdir/ops-values-no-ingress.yaml" <<'YAML'
ingress:
  enabled: false
YAML

resolved_url_empty="$(resolve_ops_server_url "$tmpdir/ops-values-no-ingress.yaml" 2>/dev/null || true)"
if [[ -n "$resolved_url_empty" ]]; then
  echo "resolve_ops_server_url: expected empty result for missing ingress host, got $resolved_url_empty"
  exit 1
fi

if [[ "$(default_globalserver_base_url dev)" != "https://www.gs.us-west-2.aws.observability-dev.pingcap.cloud" ]]; then
  echo "unexpected dev globalserver URL"
  exit 1
fi

if [[ "$(default_globalserver_base_url staging)" != "https://www.gs.us-west-2.aws.observability-staging.pingcap.cloud" ]]; then
  echo "unexpected staging globalserver URL"
  exit 1
fi

if [[ "$(default_globalserver_base_url prod)" != "https://www.gs.us-west-2.aws.observability.tidbcloud.com" ]]; then
  echo "unexpected prod globalserver URL"
  exit 1
fi

if [[ "$(resolve_managed_ops_api_base_url dev)" != "https://www.gs.us-west-2.aws.observability-dev.pingcap.cloud" ]]; then
  echo "managed ops API base URL should come from the environment mapping"
  exit 1
fi

bootstrap_off_url="$(BOOTSTRAP=false resolve_effective_ops_api_base_url "https://www.gs.example.com")"
if [[ "$bootstrap_off_url" != "https://www.gs.example.com" ]]; then
  echo "resolve_effective_ops_api_base_url: expected global URL when bootstrap is disabled, got $bootstrap_off_url"
  exit 1
fi

fakebin="$(mktemp -d)"
trap 'rm -rf "$tmpdir" "$fake_helm_bin" "$old_helm_bin" "$fakebin"' EXIT
export TEST_KUBECTL_LOG="$tmpdir/kubectl.log"
: >"$TEST_KUBECTL_LOG"

cat >"$fakebin/kubectl" <<'EOF'
#!/usr/bin/env bash
echo "$*" >> "$TEST_KUBECTL_LOG"
if [[ "$*" == "-n ops-system get helmrelease ops-server" ]]; then
  exit "${KUBECTL_HELMRELEASE_STATUS:-0}"
fi
if [[ "$1" == "-n" && "$2" == "ops-system" && "$3" == "rollout" && "$4" == "status" && "$5" == "deployment/ops-server" ]]; then
  exit "${KUBECTL_ROLLOUT_STATUS:-0}"
fi
if [[ "$1" == "-n" && "$2" == "ops-system" && "$3" == "wait" && "$4" == "--for=condition=Ready" && "$5" == "helmrelease/ops-server" ]]; then
  exit "${KUBECTL_HELMRELEASE_WAIT_STATUS:-0}"
fi
if [[ "$1" == "-n" && "$2" == "ops-system" && "$3" == "port-forward" && "$4" == "svc/ops-server" ]]; then
  sleep "${FAKE_PORT_FORWARD_SLEEP:-10}"
  exit 0
fi
exit 99
EOF
chmod +x "$fakebin/kubectl"
PATH="$fakebin:$PATH"

export KUBECTL_HELMRELEASE_STATUS=0
if should_bootstrap_managed_deploy; then
  echo "bootstrap should be skipped when the HelmRelease already exists"
  exit 1
fi

export KUBECTL_HELMRELEASE_STATUS=1
if ! should_bootstrap_managed_deploy; then
  echo "bootstrap should run when the HelmRelease does not exist"
  exit 1
fi

cat >"$fakebin/curl" <<'EOF'
#!/usr/bin/env bash
if [[ "$*" == *"/oauth/token"* ]]; then
  cat <<'JSON'
{"access_token":"test-token","token_type":"Bearer"}
JSON
  exit 0
fi
if [[ "${FAIL_ON_OPS_SERVER_HELMRELEASE_CURL:-false}" == "true" && "$*" == *"/ops/api/v1/helmreleases/ops-server"* ]]; then
  echo "unexpected bootstrap wait through ops-server API" >&2
  exit 98
fi
if [[ "$*" == *"http://127.0.0.1:18180/ops/api/v1/"* ]]; then
  cat <<'JSON'
{"code":0,"data":{"serviceName":"observability-ops-server"}}
JSON
  exit 0
fi
if [[ "$*" == *"/ops/api/v1/helmreleases/ops-server"* ]]; then
  cat <<'JSON'
{"code":0,"data":{"status":{"conditions":[{"type":"Ready","status":"True"}]}}}
JSON
  exit 0
fi
exit 99
EOF
chmod +x "$fakebin/curl"

export AUTH0_CLIENT_ID=test-client
export AUTH0_CLIENT_SECRET=test-secret
export KUBECTL_ROLLOUT_STATUS=0
export KUBECTL_HELMRELEASE_WAIT_STATUS=0
token="$(mint_ops_api_token)"
if [[ "$token" != "test-token" ]]; then
  echo "expected mint_ops_api_token to return test-token, got $token"
  exit 1
fi

BOOTSTRAP_OPS_API_PID=""
BOOTSTRAP_OPS_API_LOG=""
if ! BOOTSTRAP=true prepare_bootstrap_ops_api; then
  echo "prepare_bootstrap_ops_api should start the bootstrap port-forward"
  exit 1
fi
if [[ -z "${BOOTSTRAP_OPS_API_PID:-}" ]]; then
  echo "prepare_bootstrap_ops_api should keep the bootstrap port-forward PID in the parent shell"
  exit 1
fi
if ! kill -0 "$BOOTSTRAP_OPS_API_PID" >/dev/null 2>&1; then
  echo "prepare_bootstrap_ops_api should leave the bootstrap port-forward running"
  exit 1
fi
if ! trap -p EXIT | grep -q "cleanup_bootstrap_ops_api"; then
  echo "prepare_bootstrap_ops_api should register bootstrap cleanup on EXIT"
  exit 1
fi
if ! trap -p EXIT | grep -Fq 'rm -rf "$tmpdir" "$fake_helm_bin" "$old_helm_bin" "$fakebin"'; then
  echo "prepare_bootstrap_ops_api should preserve existing EXIT trap handlers"
  exit 1
fi

bootstrap_on_url="$(BOOTSTRAP=true resolve_effective_ops_api_base_url "https://www.gs.example.com")"
if [[ "$bootstrap_on_url" != "http://127.0.0.1:18180" ]]; then
  echo "resolve_effective_ops_api_base_url: expected local bootstrap URL, got $bootstrap_on_url"
  exit 1
fi
grep -q -- "-n ops-system rollout status deployment/ops-server --timeout=5m" "$TEST_KUBECTL_LOG"
grep -q -- "-n ops-system port-forward svc/ops-server 18180:8180" "$TEST_KUBECTL_LOG"
rollout_line="$(grep -n -- "-n ops-system rollout status deployment/ops-server --timeout=5m" "$TEST_KUBECTL_LOG" | head -n 1 | cut -d: -f1)"
port_forward_line="$(grep -n -- "-n ops-system port-forward svc/ops-server 18180:8180" "$TEST_KUBECTL_LOG" | head -n 1 | cut -d: -f1)"
if [[ "$rollout_line" -ge "$port_forward_line" ]]; then
  echo "prepare_bootstrap_ops_api should verify ops-server rollout before port-forward"
  exit 1
fi

cleanup_bootstrap_ops_api

headers_json="$(build_ops_api_headers "test-token" "aws-us-west-2" "us-west-2-byoc-0303")"
echo "$headers_json" | jq -e '."Authorization" == "Bearer test-token"' >/dev/null
echo "$headers_json" | jq -e '."X-Region-Id" == "aws-us-west-2"' >/dev/null
echo "$headers_json" | jq -e '."X-Logical-Region" == "us-west-2-byoc-0303"' >/dev/null

export FAIL_ON_OPS_SERVER_HELMRELEASE_CURL=true
BOOTSTRAP=true wait_for_helmrelease_ready "http://127.0.0.1:18180" "ops-server" "aws-us-west-2" "us-west-2-byoc-0303" 5
unset FAIL_ON_OPS_SERVER_HELMRELEASE_CURL
grep -q -- "-n ops-system wait --for=condition=Ready helmrelease/ops-server --timeout=10m" "$TEST_KUBECTL_LOG"
cleanup_bootstrap_ops_api

export KUBECTL_HELMRELEASE_WAIT_STATUS=17
if BOOTSTRAP=true wait_for_helmrelease_ready "http://127.0.0.1:18180" "ops-server" "aws-us-west-2" "us-west-2-byoc-0303" 5; then
  echo "wait_for_helmrelease_ready should fail when bootstrap HelmRelease wait fails"
  exit 1
fi
export KUBECTL_HELMRELEASE_WAIT_STATUS=0

export KUBECTL_ROLLOUT_STATUS=23
if BOOTSTRAP=true wait_for_helmrelease_ready "http://127.0.0.1:18180" "ops-server" "aws-us-west-2" "us-west-2-byoc-0303" 5; then
  echo "wait_for_helmrelease_ready should fail when bootstrap ops-server rollout fails"
  exit 1
fi
export KUBECTL_ROLLOUT_STATUS=0

wait_for_helmrelease_ready "https://example.gs" "ops-server" "aws-us-west-2" "us-west-2-byoc-0303" 5

echo "lib tests passed"
