#!/bin/sh
set -eu

ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
"$ROOT/scripts/bootstrap-kubernetes-tools.sh"
PATH="$ROOT/.tools/bin:$PATH"
export PATH

CLUSTER=who-need-help
MARKER="$ROOT/.tools/${CLUSTER}.owned"
CONTROL_PLANE="${CLUSTER}-control-plane"
NAMESPACE=who-need-help
SECRET_NAME=who-need-help-local
POSTGIS_IMAGE=postgis/postgis:18-3.6-alpine
POSTGIS_SOURCE="${POSTGIS_IMAGE}@sha256:05d68c7f0f19b9aa0bf7c4a2049b2e8b38b44a63116392b95726a4c913766cf6"
MAILPIT_IMAGE=axllent/mailpit:v1.30.4
MAILPIT_SOURCE="${MAILPIT_IMAGE}@sha256:5a49a77c5bdbe7c5474450b4f46348d09949df3695257729c93a30369382d4f6"

kube() {
  kubectl --context "kind-${CLUSTER}" "$@"
}

case "$(uname -m)" in
  x86_64) IMAGE_ARCH=amd64 ;;
  aarch64|arm64) IMAGE_ARCH=arm64 ;;
  *) echo "Unsupported container architecture: $(uname -m)" >&2; exit 1 ;;
esac

load_pinned_image() {
  source=$1
  local_tag=$2
  archive=$3

  docker pull --platform "linux/${IMAGE_ARCH}" "$source"
  image_id=$(docker image inspect "$source" --format '{{.Id}}')
  docker tag "$image_id" "$local_tag"
  docker image save --platform "linux/${IMAGE_ARCH}" --output "$archive" "$local_tag"
  kind load image-archive "$archive" --name "$CLUSTER"
  rm -f "$archive"
}

remove_legacy_inline_secrets() {
  legacy_secret=who-need-help-who-need-help

  # Older chart revisions rendered credentials from tracked Helm values. Once
  # the new deployments are healthy, remove the obsolete Secret and only those
  # release-history records that still contain the former inline secret keys.
  kube --namespace "$NAMESPACE" delete secret "$legacy_secret" \
    --ignore-not-found >/dev/null

  for revision in $(
    helm history who-need-help \
      --kube-context "kind-${CLUSTER}" \
      --namespace "$NAMESPACE" |
      awk 'NR > 1 {print $1}'
  ); do
    if helm get values who-need-help \
      --revision "$revision" \
      --kube-context "kind-${CLUSTER}" \
      --namespace "$NAMESPACE" |
      grep -Eq '^[[:space:]]*(databaseUrl|secretKeyBase|handoverSecret|releaseCookie):'; then
      kube --namespace "$NAMESPACE" delete secret \
        --selector="owner=helm,name=who-need-help,version=${revision}"
    fi
  done
}

if kind get clusters | grep -Fxq "$CLUSTER"; then
  if [ ! -f "$MARKER" ]; then
    echo "A kind cluster named '$CLUSTER' already exists but was not created by this project." >&2
    echo "Refusing to modify it. Rename/remove it yourself or inspect it first." >&2
    exit 1
  fi

  if [ "$(docker inspect "$CONTROL_PLANE" \
    --format '{{index .Config.Labels "io.x-k8s.kind.cluster"}}:{{index .Config.Labels "io.x-k8s.kind.role"}}')" \
    != "$CLUSTER:control-plane" ]; then
    echo "The existing kind control-plane container is outside this project's scope." >&2
    exit 1
  fi

  if [ "$(docker inspect "$CONTROL_PLANE" --format '{{.State.Running}}')" != true ]; then
    docker start "$CONTROL_PLANE" >/dev/null
    echo "Resumed the stopped project-owned kind control plane."
  fi
else
  kind create cluster --config "$ROOT/deploy/kind/cluster.yaml"
  touch "$MARKER"
fi

load_pinned_image "$POSTGIS_SOURCE" "$POSTGIS_IMAGE" "$ROOT/.tools/postgis-kind.tar"
load_pinned_image "$MAILPIT_SOURCE" "$MAILPIT_IMAGE" "$ROOT/.tools/mailpit-kind.tar"

docker build --tag who-need-help:local "$ROOT"
kind load docker-image who-need-help:local --name "$CLUSTER"

kube create namespace "$NAMESPACE" --dry-run=client --output=yaml | kube apply -f -

legacy_backup=
if kube --namespace "$NAMESPACE" get deployment postgis >/dev/null 2>&1; then
  backup_dir="$ROOT/output/backups"
  mkdir -p "$backup_dir"
  umask 077
  legacy_backup="$backup_dir/kind-who-need-help-$(date +%Y%m%d-%H%M%S).dump"
  kube --namespace "$NAMESPACE" exec deployment/postgis -- \
    pg_dump --username postgres --dbname who_need_help --format custom >"$legacy_backup"
  test -s "$legacy_backup"
  kube --namespace "$NAMESPACE" exec --stdin deployment/postgis -- \
    pg_restore --list <"$legacy_backup" >/dev/null
  echo "Validated legacy kind database backup: $legacy_backup"
fi

if ! kube --namespace "$NAMESPACE" get secret "$SECRET_NAME" >/dev/null 2>&1; then
  if kube --namespace "$NAMESPACE" get statefulset postgis >/dev/null 2>&1; then
    echo "Secret '$SECRET_NAME' is missing while the persistent PostGIS StatefulSet exists." >&2
    echo "Refusing to generate credentials that would not match the existing database." >&2
    exit 1
  fi

  postgres_password=$(openssl rand -hex 32)
  secret_key_base=$(openssl rand -hex 64)
  handover_secret=$(openssl rand -hex 64)
  release_cookie=$(openssl rand -hex 64)
  metrics_token=$(openssl rand -hex 32)

  kube --namespace "$NAMESPACE" create secret generic "$SECRET_NAME" \
    --from-literal=POSTGRES_DB=who_need_help \
    --from-literal=POSTGRES_USER=postgres \
    --from-literal="POSTGRES_PASSWORD=$postgres_password" \
    --from-literal="DATABASE_URL=ecto://postgres:${postgres_password}@postgis/who_need_help" \
    --from-literal="SECRET_KEY_BASE=$secret_key_base" \
    --from-literal="HANDOVER_SECRET=$handover_secret" \
    --from-literal="RELEASE_COOKIE=$release_cookie" \
    --from-literal="METRICS_TOKEN=$metrics_token"

  unset postgres_password secret_key_base handover_secret release_cookie metrics_token
elif [ -z "$(kube --namespace "$NAMESPACE" get secret "$SECRET_NAME" -o jsonpath='{.data.METRICS_TOKEN}')" ]; then
  metrics_token=$(openssl rand -hex 32)

  kube --namespace "$NAMESPACE" patch secret "$SECRET_NAME" \
    --type merge \
    --patch "{\"stringData\":{\"METRICS_TOKEN\":\"$metrics_token\"}}" >/dev/null

  unset metrics_token
fi

if [ -n "$legacy_backup" ]; then
  kube --namespace "$NAMESPACE" delete deployment postgis --wait=true
fi

kube --namespace "$NAMESPACE" apply -f "$ROOT/deploy/kind/dependencies.yaml"
kube --namespace "$NAMESPACE" rollout status statefulset/postgis
kube --namespace "$NAMESPACE" rollout status deployment/mailpit

if [ -n "$legacy_backup" ]; then
  kube --namespace "$NAMESPACE" exec --stdin statefulset/postgis -- \
    pg_restore --username postgres --dbname who_need_help \
    --clean --if-exists --no-owner <"$legacy_backup"
  echo "Restored legacy kind database backup."
fi

helm upgrade --install who-need-help "$ROOT/deploy/helm/who-need-help" \
  --kube-context "kind-${CLUSTER}" \
  --namespace "$NAMESPACE" \
  --values "$ROOT/deploy/helm/who-need-help/values-kind.yaml" \
  --set-string app.codexSessionId="${CODEX_SESSION_ID:-${CODEX_THREAD_ID:-not-configured}}" \
  --wait

kube --namespace "$NAMESPACE" rollout restart \
  deployment/who-need-help-who-need-help-web \
  deployment/who-need-help-who-need-help-worker
kube --namespace "$NAMESPACE" rollout status deployment/who-need-help-who-need-help-web
kube --namespace "$NAMESPACE" rollout status deployment/who-need-help-who-need-help-worker
remove_legacy_inline_secrets
"$ROOT/scripts/verify-realtime-cluster.sh" kind
"$ROOT/scripts/verify-beam-runtime.sh" kind

echo "Who Need Help: http://localhost:4011"
echo "Mailpit:       http://localhost:8028"
