#!/usr/bin/env bash
#MISE description="Statically validate the k8s surface (charts + Flux tree)"
#MISE dir="{{config_root}}"
# Renders every chart (helm template + kubeconform) and builds the whole Flux
# tree the way Flux would (flux-local --enable-helm). No cluster needed; this
# is the CI gate for kubernetes/ and charts/ changes.
#
# NB: don't run this while Tilt is converging — Tilt's helm-deps resource
# rebuilds charts/*/charts/ (rm -rf + dependency build) and races the renders.
set -euo pipefail

# Charts are role-grouped: apps/* (services), platform/* (operators/CRs),
# lib/yucca-common (shared library), dev/mock-oidc (dev-only). Paths below are
# relative to charts/.
LIB_CONSUMERS=(apps/yucca-api apps/yucca-admin-api apps/yucca-metrics-worker apps/web apps/michael dev/mock-oidc)
ALL_CHARTS=(apps/yucca-api apps/yucca-admin-api apps/yucca-metrics-worker apps/web apps/michael dev/mock-oidc platform/cnpg-cluster platform/ceph-objectuser platform/rook-ceph-cluster)

echo "==> helm dependency build (yucca-common consumers)"
for c in "${LIB_CONSUMERS[@]}"; do
  (cd "charts/$c" && helm dependency build >/dev/null)
done

echo "==> helm template + kubeconform"
for c in "${ALL_CHARTS[@]}"; do
  ns=yucca
  [ "$c" = "platform/rook-ceph-cluster" ] && ns=rook-ceph
  # NB: release name must not be YAML-boolean-ish ("y"/"on"/...): it lands in
  # labels and kubeconform reads it back as a bool.
  helm template yucca "charts/$c" -n "$ns" \
    | kubeconform -strict -ignore-missing-schemas - \
    && echo "    OK  $c"
done

echo "==> kustomize build (Flux entrypoints)"
# partition/region GitOps tree: per-cluster entry points (clusters/<p>/<r>) +
# app overlays (apps/<p>/<r>, which compose components/{infra,roles/<role>}).
# LoadRestrictionsNone mirrors how Flux's kustomize-controller builds within a
# single git artifact: the role Components reference ../../apps/<app>.yaml
# (a sibling subtree under components/), which the CLI's default RootOnly
# restrictor would reject even though Flux allows it.
kb() { kustomize build --load-restrictor=LoadRestrictionsNone "$@"; }
CLUSTERS=(staging/austin prod/htz-fsn1 dev/local)
for c in "${CLUSTERS[@]}"; do
  kb "kubernetes/clusters/$c" >/dev/null && echo "    OK  kubernetes/clusters/$c"
  kb "kubernetes/apps/$c" >/dev/null && echo "    OK  kubernetes/apps/$c"
done
# Dev-mirror HelmRepository sources (consumed by Tilt + the dev cluster-repos
# Kustomization; kept validated too).
kb kubernetes/apps/dev/local/repos >/dev/null && echo "    OK  kubernetes/apps/dev/local/repos"

echo "==> prod guardrails (no dev IdP behind the primary app set)"
# The prod cluster-settings carry a placeholder dev OIDC issuer until the real
# IdP exists; this gate makes it mechanically impossible to enable the yucca
# workload set (components/roles/primary) against it. Staging legitimately uses
# the dev issuer, so only prod overlays are checked.
for kz in kubernetes/apps/prod/*/kustomization.yaml; do
  region_dir=$(basename "$(dirname "$kz")")
  settings="kubernetes/clusters/prod/$region_dir/cluster-settings.yaml"
  # primary role enabled = an UNcommented components entry referencing roles/primary
  if grep -Eq '^[[:space:]]*-[[:space:]].*components/roles/primary' "$kz"; then
    if grep -Eq '^[[:space:]]*OIDC_ISSUER:.*(external-dev-|mock-oidc)' "$settings"; then
      echo "FAIL: prod/$region_dir enables roles/primary but $settings still points at a dev OIDC issuer" >&2
      exit 1
    fi
  fi
done
echo "    OK  prod OIDC guard"

echo "==> flux-local build (full tree, helm rendering as Flux would)"
# Via uvx so uv supplies a Python matching flux-local's requires-python
# (>=3.13) regardless of the host. One retry: flux-local fans out `flux build
# ks` subprocesses which very rarely segfault under load.
flux_local() { uvx --from "flux-local==8.2.0" flux-local "$@"; }
# Per-cluster path: clusters reuse the same Kustomization names (cluster-apps,
# flux-system ns), so flux-local must scope to one cluster at a time.
for c in "${CLUSTERS[@]}"; do
  flux_local build all "kubernetes/clusters/$c" --enable-helm --no-enable-dns >/dev/null \
    || flux_local build all "kubernetes/clusters/$c" --enable-helm --no-enable-dns >/dev/null
  echo "    OK  flux-local ($c)"
done

echo "k8s surface: ALL VALID"
