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

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel)"
source "$REPO_ROOT/deployments/drhouse/common.sh"
EXPECTED_CLUSTER_ARN="${EXPECTED_CLUSTER_ARN:-arn:aws:eks:us-west-2:227896186585:cluster/o11y-dev-us-west-2-byoc-0303}"

adoption_validate_cluster_context() {
  local current
  current="$(kubectl config current-context)"
  [[ "$current" == "$EXPECTED_CLUSTER_ARN" ]] || {
    echo "ERROR: current context $current, expected $EXPECTED_CLUSTER_ARN" >&2
    return 1
  }
}

normalize_adoption_manifest() {
  local input="$1"
  yq eval -o=json '
    del(
      .metadata.annotations."meta.helm.sh/release-name",
      .metadata.annotations."meta.helm.sh/release-namespace",
      .metadata.annotations."kubectl.kubernetes.io/last-applied-configuration",
      .metadata.labels."app.kubernetes.io/managed-by",
      .metadata.labels."helm.toolkit.fluxcd.io/name",
      .metadata.labels."helm.toolkit.fluxcd.io/namespace",
      .metadata.creationTimestamp,
      .metadata.resourceVersion,
      .metadata.uid,
      .metadata.generation,
      .metadata.managedFields,
      .status,
      .spec.persistentVolumeClaimRetentionPolicy,
      .spec.podManagementPolicy,
      .spec.revisionHistoryLimit,
      .spec.serviceName,
      .spec.updateStrategy,
      .spec.template.spec.dnsPolicy,
      .spec.template.spec.restartPolicy,
      .spec.template.spec.schedulerName,
      .spec.template.spec.securityContext,
      .spec.template.spec.terminationGracePeriodSeconds,
      .spec.template.spec.containers[].terminationMessagePath,
      .spec.template.spec.containers[].terminationMessagePolicy,
      .spec.template.metadata.creationTimestamp,
      .spec.template.spec.containers[].env[].valueFrom.fieldRef.apiVersion,
      .spec.template.spec.containers[].ports[].protocol,
      .spec.volumeClaimTemplates[].status,
      .spec.volumeClaimTemplates[].metadata.creationTimestamp,
      .spec.jobTemplate.metadata,
      .spec.jobTemplate.spec.template.metadata
    )
  ' "$input" | jq -S '
    if .metadata.annotations == {} then del(.metadata.annotations) else . end
    | if .metadata.labels == {} then del(.metadata.labels) else . end
    | if .kind == "Service" then
        del(
          .spec.clusterIP,
          .spec.clusterIPs,
          .spec.internalTrafficPolicy,
          .spec.ipFamilies,
          .spec.ipFamilyPolicy,
          .spec.sessionAffinity
        )
        | if .spec.type == "ClusterIP" then del(.spec.type) else . end
      else
        .
      end
  '
}

render_scoped_release() {
  local release_name="$1"
  local chart_dir="$2"
  local env_values="$3"
  local image_values="$4"
  local args=("$release_name" "$chart_dir")

  if [[ -f "$chart_dir/values.yaml" ]]; then
    args+=(-f "$chart_dir/values.yaml")
  fi
  args+=(-f "$env_values" -f "$image_values")

  helm template "${args[@]}"
}

compare_rendered_to_live() {
  local render_file="$1"
  local manifest_kind="$2"
  local resource_type="$3"
  local name="$4"
  local namespace="$5"
  local rendered="$workdir/rendered-${resource_type}-${name}.yaml"
  local live="$workdir/live-${resource_type}-${name}.yaml"

  yq eval "select(.kind == \"$manifest_kind\" and .metadata.name == \"$name\")" "$render_file" >"$rendered"
  if [[ ! -s "$rendered" ]]; then
    echo "ERROR: rendered resource ${manifest_kind}/${name} not found in ${render_file}" >&2
    return 1
  fi

  kubectl -n "$namespace" get "$resource_type" "$name" -o yaml >"$live"

  normalize_adoption_manifest "$rendered" >"${rendered}.norm"
  normalize_adoption_manifest "$live" >"${live}.norm"
  diff -u "${live}.norm" "${rendered}.norm"
}

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  adoption_validate_cluster_context

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

  render_scoped_release \
    diagnosis-query \
    "$REPO_ROOT/deployments/charts/diagnosis-query" \
    "$REPO_ROOT/deployments/drhouse/diagnosis-query/envs/dev-aws-us-west-2-byoc-0303/values.yaml" \
    "$(resolve_image_tag_file "$REPO_ROOT/deployments/drhouse/diagnosis-query" dev aws us-west-2-byoc-0303)" >"$workdir/diagnosis-query.yaml"

  render_scoped_release \
    o11ydiagnosis-deltalake \
    "$REPO_ROOT/deployments/charts/o11ydiagnosis-deltalake" \
    "$REPO_ROOT/deployments/drhouse/o11ydiagnosis-deltalake/envs/dev-aws-us-west-2-byoc-0303/values.yaml" \
    "$(resolve_image_tag_file "$REPO_ROOT/deployments/drhouse/o11ydiagnosis-deltalake" dev aws us-west-2-byoc-0303)" >"$workdir/o11ydiagnosis-deltalake.yaml"

  compare_rendered_to_live "$workdir/diagnosis-query.yaml" StatefulSet statefulset diagnosis-query observability
  compare_rendered_to_live "$workdir/diagnosis-query.yaml" Service service diagnosis-query observability
  compare_rendered_to_live "$workdir/diagnosis-query.yaml" Ingress ingress diagnosis-query observability
  compare_rendered_to_live "$workdir/diagnosis-query.yaml" ServiceMonitor servicemonitor diagnosis-query-monitor self-monitoring
  compare_rendered_to_live "$workdir/o11ydiagnosis-deltalake.yaml" StatefulSet statefulset o11ydiagnosis-deltalake observability
  compare_rendered_to_live "$workdir/o11ydiagnosis-deltalake.yaml" PodMonitor podmonitor o11ydiagnosis-deltalake-monitor self-monitoring
  compare_rendered_to_live "$workdir/o11ydiagnosis-deltalake.yaml" CronJob cronjob task-collector observability
fi
