#!/usr/bin/env bash
# scripts/juju-spaces-check.sh [MODEL]
#
# Read-only juju identity + per-model SPACE assertion. Spaces are per-model in Juju,
# so this runs AFTER 'juju add-model' and before 'juju deploy'. Default MODEL=openstack.
# Asserts the six D-052/D-053 spaces present and the five stale names absent.
#
# Pinned values come from scripts/lib-net.sh (single source of truth).
# Exit codes: 0 pass | 1 fatal (missing/stale spaces, or juju error) | 2 model not present yet

set -euo pipefail
shopt -s inherit_errexit 2>/dev/null || true
IFS=$'\n\t'

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/lib-net.sh
. "$SCRIPT_DIR/lib-net.sh"

FATAL=0
fail() { echo "FAIL: $*" >&2; FATAL=$((FATAL+1)); }
pass() { echo "PASS: $*"; }
note() { echo "NOTE: $*"; }

MODEL="${1:-openstack}"
need_jq || exit 2

# whoami first, DIRECTLY (not in a command substitution) so an auth/macaroon
# password prompt can reach the terminal before any captured juju call.
echo "=== juju identity ==="
juju whoami || true
echo
echo "=== models ==="
juju models 2>&1 | sed 's/^/  /' || true
echo

# Is MODEL present? Strip any owner/ prefix; match the bare model name.
# Capture-then-test (DOCFIX-115): the live-pipe form (juju | jq | grep -qx)
# raced SIGPIPE under pipefail and masked a juju auth failure as "model not
# present". A failed 'juju models' now takes the macaroon-hint path instead.
MJSON="$(juju models --format json)" || { fail "juju models failed (auth/macaroon? re-login or append </dev/tty)"; echo; echo "Summary: 1 fatal"; exit 1; }
MNAMES="$(jq -r '.models[]?.name' <<<"$MJSON" 2>/dev/null | sed 's#.*/##')" || true
if ! grep -qx "$MODEL" <<<"$MNAMES"; then
  note "model '$MODEL' not present yet -- run 'juju add-model $MODEL' first (spaces are per-model)"
  echo
  echo "Summary: model-absent (run add-model, then re-run this check)"
  exit 2
fi
pass "model '$MODEL' present"

echo
echo "=== spaces in model '$MODEL' (want six; none of the five stale) ==="
SPJSON="$(juju spaces -m "$MODEL" --format json)" || { fail "juju spaces failed (auth/macaroon? re-login or append </dev/tty)"; echo; echo "Summary: 1 fatal"; exit 1; }
# FIXED 2026-07-10 (full-project sweep): appended `|| true`. This file runs
# under `set -e`+pipefail (see the DOCFIX-115 comment elsewhere in this
# file about this exact hazard) -- every other juju/jq call here is already
# `|| true`-guarded, this one line was the sole exception. If `.spaces` is
# null/absent (a genuinely empty freshly-added model -- exactly the
# scenario this script is meant to be run against), jq exits non-zero,
# pipefail propagates it, and the bare pipeline kills the whole script
# before the SPACES6 FATAL-accumulation loop below ever runs. Safe to use
# `|| true` here specifically (unlike a case needing PIPESTATUS
# afterward): this line is PURELY for display, and the HAVE array used by
# the actual pass/fail logic below is built by its own, independent jq
# call (the next line), not by inspecting this line's exit status.
echo "$SPJSON" | jq -r '.spaces[].name' | sort | sed 's/^/    /' || true

mapfile -t HAVE < <(echo "$SPJSON" | jq -r '.spaces[].name')
have_has() { local x; for x in "${HAVE[@]}"; do [ "$x" = "$1" ] && return 0; done; return 1; }

for s in "${SPACES6[@]}"; do
  if have_has "$s"; then pass "present: $s"; else fail "MISSING: $s (deploy fails 'space not found')"; fi
done
for s in "${STALE_SPACES[@]}"; do
  if have_has "$s"; then fail "STALE STILL PRESENT: $s (run 'juju reload-spaces -m $MODEL')"; fi
done

echo
echo "Summary: ${FATAL} fatal"
if [ "$FATAL" -gt 0 ]; then exit 1; fi
exit 0
