#!/usr/bin/env bash
# kai-scheduler/kai-scheduler v0.16.9 - base variant: default
# Path: pull the package, render this base variant locally, read the objects,
# then apply them with kubectl. No ConfigHub account is needed.
# Generated by scripts/generate-public-site.mjs from the committed package
# data for this base variant. Chart page: https://confighub.github.io/helm-expt/site/charts/kai-scheduler-kai-scheduler-v0-16-9.html
set -euo pipefail

say() { printf '\n>> %s\n' "$*"; }

if ! command -v cub >/dev/null 2>&1; then
  printf 'cub is not installed. Install the cub CLI with:\n  curl -fsSL https://hub.confighub.com/cub/install.sh | bash\nthen add ~/.confighub/bin to your PATH and re-run this script.\n' >&2
  exit 1
fi

# Installer is a cub plugin. Check it before this script does any work.
if ! cub installer --help >/dev/null 2>&1; then
  printf 'The cub installer plugin is missing. Follow https://confighub.github.io/helm-expt/site/try.html#install-cub, then re-run this script.\n' >&2
  exit 1
fi

if ! command -v kustomize >/dev/null 2>&1; then
  printf 'kustomize is missing. Follow https://confighub.github.io/helm-expt/site/try.html#install-cub, then re-run this script.\n' >&2
  exit 1
fi

if ! command -v kubectl >/dev/null 2>&1; then
  printf 'kubectl is required for the apply step.\n' >&2
  exit 1
fi

say "Pull the package and render the default base variant into ./kai-scheduler-kai-scheduler-v0-16-9-default"
cub installer setup --pull oci://europe-west1-docker.pkg.dev/nth-fort-499605-q5/helm-expt/kai-scheduler-kai-scheduler:v0.16.9@sha256:7d360f97ada7c492e506acdd433c9212d21f5a6d26d8d8cbf1f0b68a268e94ab --base default --work-dir ./kai-scheduler-kai-scheduler-v0-16-9-default --non-interactive --namespace kai-scheduler

say "Read what was rendered; nothing has touched the cluster yet"
ls ./kai-scheduler-kai-scheduler-v0-16-9-default/out/manifests

wait_for_crd() {
  crd_name="$1"
  deadline=$(( $(date +%s) + 180 ))
  until kubectl get "crd/${crd_name}" >/dev/null 2>&1; do
    if [ "$(date +%s)" -ge "$deadline" ]; then
      printf "CRD %s did not appear within 180 seconds.\n" "$crd_name" >&2
      return 1
    fi
    sleep 2
  done
  kubectl wait --for=condition=Established --timeout=120s "crd/${crd_name}"
}

say "Ensure the kai-scheduler namespace exists"
kubectl create namespace kai-scheduler --dry-run=client -o yaml | kubectl apply -f -

say "Check 6 CRDs included with this package"
missing_crds=0
if ! kubectl get crd/bindrequests.scheduling.run.ai >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/configs.kai.scheduler >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/podgroups.scheduling.run.ai >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/queues.scheduling.run.ai >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/schedulingshards.kai.scheduler >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/topologies.kai.scheduler >/dev/null 2>&1; then
  missing_crds=1
fi
if [ "$missing_crds" -eq 1 ]; then
  kubectl apply --server-side -f ./kai-scheduler-kai-scheduler-v0-16-9-default/package/prerequisites/target-facts/default-crds.yaml
elif kubectl diff --server-side -f ./kai-scheduler-kai-scheduler-v0-16-9-default/package/prerequisites/target-facts/default-crds.yaml >/dev/null 2>&1; then
  say "The required CRDs already exist and match this package; leave them under their current owner"
elif [ "${APPLY_CRDS:-0}" = "1" ]; then
  say "The existing CRDs differ from this package. APPLY_CRDS=1 is set, so apply the package's CRDs"
  kubectl apply --server-side -f ./kai-scheduler-kai-scheduler-v0-16-9-default/package/prerequisites/target-facts/default-crds.yaml
else
  say "The CRDs already exist and differ from this package, or another tool owns them"
  cat <<'EOF_CRDS'
This script does not change CRDs it did not just create.
If this is an upgrade, the objects that follow may need the newer CRDs.
To let this script apply the package's CRDs, re-run with:
  APPLY_CRDS=1 bash try.sh
EOF_CRDS
  exit 1
fi
wait_for_crd bindrequests.scheduling.run.ai
wait_for_crd configs.kai.scheduler
wait_for_crd podgroups.scheduling.run.ai
wait_for_crd queues.scheduling.run.ai
wait_for_crd schedulingshards.kai.scheduler
wait_for_crd topologies.kai.scheduler

say "Before an install or an upgrade, move the CRDs forward and migrate topologies"
hook_dir="$(mktemp -d)"
awk -v dir="$hook_dir" 'BEGIN{n=0} /^---[[:space:]]*$/{n++; next} {print > (dir "/doc-" n ".yaml")}' ./kai-scheduler-kai-scheduler-v0-16-9-default/package/prerequisites/kai-scheduler-lifecycle/default/pre-install-pre-upgrade.yaml
kubectl apply -f "$hook_dir/doc-2.yaml" -f "$hook_dir/doc-5.yaml" -f "$hook_dir/doc-7.yaml"
kubectl apply -f "$hook_dir/doc-1.yaml" -f "$hook_dir/doc-4.yaml" -f "$hook_dir/doc-6.yaml"
kubectl apply -f "$hook_dir/doc-8.yaml"
kubectl -n kai-scheduler wait --for=condition=complete --timeout=300s job/crd-upgrader
kubectl apply -f "$hook_dir/doc-3.yaml"
kubectl apply -f "$hook_dir/doc-9.yaml"
kubectl -n kai-scheduler wait --for=condition=complete --timeout=300s job/topology-migration
kubectl delete --ignore-not-found -f ./kai-scheduler-kai-scheduler-v0-16-9-default/package/prerequisites/kai-scheduler-lifecycle/default/pre-install-pre-upgrade.yaml
rm -rf "$hook_dir"

if [ -d ./kai-scheduler-kai-scheduler-v0-16-9-default/out/secrets ]; then
  say "Apply rendered Secrets first"
  kubectl apply -f ./kai-scheduler-kai-scheduler-v0-16-9-default/out/secrets
fi

say "Apply the rendered objects, except the CRDs already settled above"
settled_crds=" bindrequests.scheduling.run.ai configs.kai.scheduler podgroups.scheduling.run.ai queues.scheduling.run.ai schedulingshards.kai.scheduler topologies.kai.scheduler "
manifest_args=()
for manifest in ./kai-scheduler-kai-scheduler-v0-16-9-default/out/manifests/*.yaml; do
  if grep -q '^kind: CustomResourceDefinition$' "$manifest"; then
    crd_name="$(awk '/^metadata:/{m=1; next} m && /^  name:/{print $2; exit}' "$manifest")"
    case "$settled_crds" in
      *" $crd_name "*) continue ;;
    esac
  fi
  manifest_args+=(-f "$manifest")
done
if [ "${#manifest_args[@]}" -gt 0 ]; then
  kubectl apply "${manifest_args[@]}"
fi

say "After an install or an upgrade, apply the Config that tells the operator what to run"
hook_dir="$(mktemp -d)"
awk -v dir="$hook_dir" 'BEGIN{n=0} /^---[[:space:]]*$/{n++; next} {print > (dir "/doc-" n ".yaml")}' ./kai-scheduler-kai-scheduler-v0-16-9-default/package/prerequisites/kai-scheduler-lifecycle/default/post-install-post-upgrade.yaml
kubectl apply -f "$hook_dir/doc-1.yaml" -f "$hook_dir/doc-2.yaml" -f "$hook_dir/doc-3.yaml" -f "$hook_dir/doc-4.yaml"
kubectl apply -f "$hook_dir/doc-5.yaml"
kubectl -n kai-scheduler wait --for=condition=complete --timeout=300s job/kai-config-deployer
kubectl delete --ignore-not-found -f ./kai-scheduler-kai-scheduler-v0-16-9-default/package/prerequisites/kai-scheduler-lifecycle/default/post-install-post-upgrade.yaml
rm -rf "$hook_dir"

say "Done. The cluster received the files in ./kai-scheduler-kai-scheduler-v0-16-9-default/out. Its CRDs were settled first, from the package. 2 packaged steps ran with the apply."
say "Not run by this script: the post-delete step of this base's plan. The entry page says who runs it."
