#!/bin/sh
set -eu

usage() {
  echo "usage: $0 <kubeconfig> <context> <evidence-dir> <session-context>" >&2
  exit 2
}

[ "$#" -eq 4 ] || usage

script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
repo_root=$(git -C "$script_dir" rev-parse --show-toplevel)
source_branch=$(git -C "$repo_root" branch --show-current)
source_commit=$(git -C "$repo_root" rev-parse HEAD)
[ -n "$source_branch" ] || {
  echo "O11Y proof requires a named source branch" >&2
  exit 1
}
[ -z "$(git -C "$repo_root" status --porcelain)" ] || {
  echo "O11Y proof requires a clean source branch" >&2
  exit 1
}
kubeconfig=$1
context=$2
evidence_dir=$3
session_context=$4
namespace=observability
session_name=$(jq -er '.session_name' "$session_context")
target_region=$(jq -er '.target.region' "$session_context")
endpoint_service_name=$(jq -er '.host.remote.o11y_endpoint_service_name' "$session_context")
expected_dns_name=$(
  python3 - "$session_context" <<'PY'
import json
import sys
import urllib.parse

with open(sys.argv[1], encoding="utf-8") as handle:
    context = json.load(handle)
public_url = str(
    (((context.get("host") or {}).get("remote") or {}).get("public_https_url"))
    or ""
).strip()
public_host = urllib.parse.urlparse(public_url).hostname or ""
if not public_host:
    raise SystemExit("O11Y proof requires host.remote.public_https_url")
print("o11y." + public_host)
PY
)

run_kubectl() {
  KUBECONFIG="$kubeconfig" kubectl --context "$context" --namespace "$namespace" "$@"
}

run_kubectl create configmap o11y-platform-contract \
  --from-file=contract-tracer.py="$script_dir/contract-tracer.py" \
  --from-file=proof_client.py="$script_dir/proof_client.py" \
  --dry-run=client -o yaml |
  run_kubectl apply -f -

run_kubectl rollout status deployment/vm-operator --timeout=180s
run_kubectl rollout status deployment/globalserver --timeout=180s
run_kubectl rollout status deployment/regionalserver --timeout=180s
run_kubectl rollout status deployment/data-server --timeout=180s
run_kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=vmstorage --timeout=180s
run_kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=vmselect --timeout=180s
run_kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=vminsert --timeout=180s

released_images=$(
  run_kubectl get deployments globalserver regionalserver data-server -o json |
    jq -c '[
      .items[] |
      .metadata.name as $workload |
      .spec.template.spec.containers[] |
      select(.name == $workload) |
      {workload: $workload, container: .name, image: .image}
    ]'
)
printf '%s' "$released_images" |
  jq -e '
    length == 3 and
    all(.[];
      (.image | contains("@sha256:")) and
      (.image | startswith("385595570414.dkr.ecr.us-west-2.amazonaws.com/observability@sha256:"))
    )
  ' >/dev/null
released_image_ids=$(
  run_kubectl get pods -o json |
    jq -c '[
      .items[] |
      .metadata.labels["app.kubernetes.io/name"] as $workload |
      select($workload == "globalserver" or $workload == "regionalserver" or $workload == "data-server") |
      .status.containerStatuses[] |
      select(.name == $workload) |
      {workload: $workload, container: .name, image: .image, imageID: .imageID, ready: .ready}
    ]'
)
printf '%s' "$released_image_ids" |
  jq -e 'length == 3 and all(.[]; .ready == true and (.imageID | contains("@sha256:")))' >/dev/null

for _ in $(seq 1 36); do
  status=$(run_kubectl get vmcluster cp9-metrics -o jsonpath='{.status.clusterStatus}')
  [ "$status" = "operational" ] && break
  sleep 5
done
[ "${status:-}" = "operational" ] || {
  echo "VMCluster cp9-metrics did not become operational" >&2
  exit 1
}

contract_pod=cp9-o11y-contract-tracer
run_kubectl delete pod "$contract_pod" --ignore-not-found --wait=true >/dev/null
trap 'run_kubectl delete pod "$contract_pod" --ignore-not-found --wait=false >/dev/null 2>&1 || true; run_kubectl delete configmap o11y-platform-contract --ignore-not-found >/dev/null 2>&1 || true' EXIT INT TERM

jq -n \
  --arg name "$contract_pod" \
  --arg namespace "$namespace" \
  --arg session "$session_name" \
  --arg region "$target_region" \
  --arg expected_dns_name "$expected_dns_name" \
  --arg endpoint_service_name "$endpoint_service_name" \
  '{
    apiVersion: "v1",
    kind: "Pod",
    metadata: {
      name: $name,
      namespace: $namespace,
      labels: {
        "app.kubernetes.io/name": "o11y-platform-contract",
        "app.kubernetes.io/part-of": "cp9-o11y"
      }
    },
    spec: {
      restartPolicy: "Never",
      activeDeadlineSeconds: 600,
      containers: [{
        name: "tracer",
        image: "public.ecr.aws/docker/library/python:3.12-alpine@sha256:6d43704baacd1bfbe7c295d7f13079d5d8104ed33568873133f8fc69980419df",
        command: ["python", "/contract/contract-tracer.py"],
        env: [
          {
            name: "PYTHONDONTWRITEBYTECODE",
            value: "1"
          },
          {
            name: "CP9_SESSION_NAME",
            value: $session
          },
          {
            name: "CP9_TARGET_REGION",
            value: $region
          },
          {
            name: "CP9_EXPECTED_DNS_NAME",
            value: $expected_dns_name
          },
          {
            name: "CP9_EXPECTED_ENDPOINT_SERVICE",
            value: $endpoint_service_name
          },
          {
            name: "CP9_AUTH0_CLIENT_ID",
            valueFrom: {
              secretKeyRef: {
                name: "cp9-o11y-runtime",
                key: "auth0-client-id"
              }
            }
          },
          {
            name: "CP9_AUTH0_CLIENT_SECRET",
            valueFrom: {
              secretKeyRef: {
                name: "cp9-o11y-runtime",
                key: "auth0-client-secret"
              }
            }
          }
        ],
        volumeMounts: [{
          name: "contract",
          mountPath: "/contract",
          readOnly: true
        }],
        securityContext: {
          runAsNonRoot: true,
          runAsUser: 65532,
          allowPrivilegeEscalation: false,
          capabilities: {drop: ["ALL"]}
        },
        resources: {
          requests: {cpu: "10m", memory: "32Mi"},
          limits: {cpu: "200m", memory: "128Mi"}
        }
      }],
      volumes: [{
        name: "contract",
        configMap: {name: "o11y-platform-contract"}
      }],
      securityContext: {
        seccompProfile: {type: "RuntimeDefault"}
      }
    }
  }' |
  run_kubectl apply -f -

contract_phase=
for _ in $(seq 1 330); do
  contract_phase=$(run_kubectl get pod "$contract_pod" -o jsonpath='{.status.phase}')
  case "$contract_phase" in
    Succeeded) break ;;
    Failed)
      run_kubectl logs "$contract_pod" >&2 || true
      echo "O11Y GS/RS contract tracer failed" >&2
      exit 1
      ;;
  esac
  sleep 2
done
[ "$contract_phase" = "Succeeded" ] || {
  run_kubectl logs "$contract_pod" >&2 || true
  echo "O11Y GS/RS contract tracer did not complete" >&2
  exit 1
}

contract_result=$(run_kubectl logs "$contract_pod")
printf '%s' "$contract_result" |
  jq -e '
    .status == "passed" and
    .cluster_status == "ACTIVE" and
    .active_clusters_before_gateway == 1 and
    .cleanup_pending == true and
    (.cluster_id | type == "string" and length > 0) and
    (.vm_account_id | type == "string" and length > 0) and
    (.vm_project_id | type == "string" and length > 0) and
    (.dns_name | type == "string" and length > 0) and
    (.endpoint_service_name | type == "string" and length > 0)
  ' >/dev/null

run_kubectl delete pod "$contract_pod" --wait=true >/dev/null
run_kubectl delete configmap o11y-platform-contract --ignore-not-found >/dev/null
trap - EXIT INT TERM

mkdir -p "$evidence_dir"
printf '%s' "$contract_result" |
jq \
  --arg namespace "$namespace" \
  --arg vmcluster "$status" \
  --arg sourceBranch "$source_branch" \
  --arg sourceCommit "$source_commit" \
  --argjson releasedImages "$released_images" \
  --argjson releasedImageIDs "$released_image_ids" \
  '. + {
    apiVersion: "cp9.o11y/v1alpha1",
    kind: "O11yPlatformReadiness",
    namespace: $namespace,
    vmcluster: $vmcluster,
    source: {
      branch: $sourceBranch,
      commit: $sourceCommit,
      clean: true
    },
    releasedImages: $releasedImages,
    releasedImageIDs: $releasedImageIDs,
    endpoints: {
      globalService: "globalserver.observability.svc.cluster.local:8080",
      regionalService: "regionalservice.observability.svc.cluster.local:8081",
      dataService: "regional-data-service.observability.svc.cluster.local:8081",
      metricsInsert: "vminsert-cp9-metrics.observability.svc.cluster.local:8480",
      metricsSelect: "vmselect-cp9-metrics.observability.svc.cluster.local:8481"
    }
  }' >"$evidence_dir/o11y-platform-readiness.json"

echo "O11Y platform readiness passed"
