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

if [ "$#" -ne 13 ]; then
  echo "usage: $0 <host-kubeconfig> <host-context> <admin-kubeconfig> <bootstrap-manifest> <regional-crds> <infra-crds> <dm-crds> <ticdc-crds> <o11y-agent-crds> <cluster-control-support> <account-list> <dm-provider> <evidence-json>" >&2
  exit 2
fi

host_kubeconfig=$1
host_context=$2
admin_kubeconfig=$3
bootstrap_manifest=$4
regional_crds=$5
infra_crds=$6
dm_crds=$7
ticdc_crds=$8
o11y_agent_crds=$9
cluster_control_support=${10}
account_list=${11}
dm_provider=${12}
evidence_json=${13}

session_context=${CP9_SESSION_CONTEXT:-}
if [ -z "$session_context" ]; then
  echo "CP9_SESSION_CONTEXT is required to materialize the session-scoped Dedicated account list" >&2
  exit 2
fi
if [ ! -f "$session_context" ]; then
  echo "CP9_SESSION_CONTEXT does not exist: $session_context" >&2
  exit 2
fi

host_kubectl=(kubectl --kubeconfig "$host_kubeconfig" --context "$host_context")
dedicated_kubectl=(kubectl --kubeconfig "$admin_kubeconfig" --context cp9-dedicated)
if ! "${dedicated_kubectl[@]}" get --raw=/readyz >/dev/null; then
  echo "Dedicated API is not ready for metadata bootstrap" >&2
  exit 1
fi

temporary_files=()
cleanup() {
  if [ "${#temporary_files[@]}" -gt 0 ]; then
    rm -f "${temporary_files[@]}"
  fi
}
trap cleanup EXIT

session_account_list=$(mktemp)
temporary_files+=("$session_account_list")
provider_config=$(mktemp)
temporary_files+=("$provider_config")
upbound_tls_key=$(mktemp)
temporary_files+=("$upbound_tls_key")
upbound_tls_cert=$(mktemp)
temporary_files+=("$upbound_tls_cert")
upbound_tls_ca=$(mktemp)
temporary_files+=("$upbound_tls_ca")
python3 "$(dirname "$0")/render-dedicated-account-contract.py" \
  --account-list "$account_list" \
  --context "$session_context" \
  --output-account-list "$session_account_list" \
  --output-provider-configs "$provider_config"
account_list=$session_account_list

"${dedicated_kubectl[@]}" apply --server-side --force-conflicts -f "$bootstrap_manifest"
for crd_directory in "$regional_crds" "$infra_crds" "$dm_crds" "$ticdc_crds" "$o11y_agent_crds"; do
  "${dedicated_kubectl[@]}" apply --server-side --force-conflicts --recursive -f "$crd_directory"
done
"${dedicated_kubectl[@]}" apply --server-side --force-conflicts -k "$cluster_control_support"
"${dedicated_kubectl[@]}" --namespace cp9-dedicated apply --server-side --force-conflicts -f "$account_list"

crds=()
while IFS= read -r crd; do
  if [ -n "$crd" ]; then
    crds+=("$crd")
  fi
done < <("${dedicated_kubectl[@]}" get crd -o name)
if [ "${#crds[@]}" -eq 0 ]; then
  echo "Dedicated API bootstrap installed zero CRDs" >&2
  exit 1
fi
crd_deadline=$((SECONDS + 180))
while true; do
  unestablished=$("${dedicated_kubectl[@]}" get crd -o json | python3 -c '
import json
import sys

items = json.load(sys.stdin).get("items") or []
pending = []
for item in items:
    conditions = ((item.get("status") or {}).get("conditions")) or []
    if not any(condition.get("type") == "Established" and condition.get("status") == "True" for condition in conditions):
        pending.append(((item.get("metadata") or {}).get("name")) or "<unnamed>")
print(" ".join(pending))
')
  if [ -z "$unestablished" ]; then
    break
  fi
  if [ "$SECONDS" -ge "$crd_deadline" ]; then
    echo "Dedicated API CRDs did not establish within 180s: $unestablished" >&2
    exit 1
  fi
  sleep 2
done

"${dedicated_kubectl[@]}" apply -f "$provider_config"
"${dedicated_kubectl[@]}" apply -f "$dm_provider"

"${host_kubectl[@]}" -n cp9-dedicated create secret generic dedicated-api-kubeconfigs \
  --from-file=regional-server.kubeconfig="$(dirname "$admin_kubeconfig")/kubeconfigs/regional-server.kubeconfig" \
  --from-file=cluster-control-server.kubeconfig="$(dirname "$admin_kubeconfig")/kubeconfigs/cluster-control-server.kubeconfig" \
  --from-file=cluster-controller.kubeconfig="$(dirname "$admin_kubeconfig")/kubeconfigs/cluster-controller.kubeconfig" \
  --from-file=webhook-server.kubeconfig="$(dirname "$admin_kubeconfig")/kubeconfigs/webhook-server.kubeconfig" \
  --from-file=o11y-agent-control-server.kubeconfig="$(dirname "$admin_kubeconfig")/kubeconfigs/o11y-agent-control-server.kubeconfig" \
  --from-file=ticdc-service.kubeconfig="$(dirname "$admin_kubeconfig")/kubeconfigs/ticdc-service.kubeconfig" \
  --from-file=classic-provider.kubeconfig="$(dirname "$admin_kubeconfig")/kubeconfigs/classic-provider.kubeconfig" \
  --dry-run=client -o yaml | "${host_kubectl[@]}" apply -f -

openssl req -x509 -newkey rsa:2048 -sha256 -nodes -days 7 \
  -subj /CN=dedicated-upbound-provider \
  -keyout "$upbound_tls_key" -out "$upbound_tls_cert" >/dev/null 2>&1
cp "$upbound_tls_cert" "$upbound_tls_ca"
"${host_kubectl[@]}" -n cp9-dedicated create secret generic dedicated-upbound-tls \
  --from-file=tls.key="$upbound_tls_key" \
  --from-file=tls.crt="$upbound_tls_cert" \
  --from-file=ca.crt="$upbound_tls_ca" \
  --dry-run=client -o yaml | "${host_kubectl[@]}" apply -f -

workload_count=$("${dedicated_kubectl[@]}" get pods,jobs,deployments,statefulsets,daemonsets --all-namespaces --ignore-not-found -o name | wc -l | tr -d ' ')
if [ "$workload_count" != "0" ]; then
  echo "metadata-only Dedicated API contains $workload_count executable workload object(s)" >&2
  "${dedicated_kubectl[@]}" get pods,jobs,deployments,statefulsets,daemonsets --all-namespaces -o wide >&2 || true
  exit 1
fi

sha256_stream() {
  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum
  else
    shasum -a 256
  fi
}
directory_digest() {
  find "$1" -type f \( -name '*.yaml' -o -name '*.yml' \) -print | LC_ALL=C sort | while IFS= read -r file; do
    cat "$file"
  done | sha256_stream | awk '{print $1}'
}
regional_digest=$(directory_digest "$regional_crds")
infra_digest=$(directory_digest "$infra_crds")
dm_digest=$(directory_digest "$dm_crds")
ticdc_digest=$(directory_digest "$ticdc_crds")
o11y_agent_digest=$(directory_digest "$o11y_agent_crds")
mkdir -p "$(dirname "$evidence_json")"
printf '{"status":"ready","authenticated_readyz":true,"metadata_workloads":0,"regional_definition_digest":"%s","infra_definition_digest":"%s","dm_definition_digest":"%s","ticdc_definition_digest":"%s","o11y_agent_definition_digest":"%s","crd_count":%d}\n' \
  "$regional_digest" "$infra_digest" "$dm_digest" "$ticdc_digest" "$o11y_agent_digest" "${#crds[@]}" >"$evidence_json"
