#!/usr/bin/env bash
# tests/dc-dc-radosgw-multisite/run-tests.sh -- offline harness for
# scripts/dc-dc-radosgw-multisite.sh. Only tests THIS SCRIPT's own logic:
# argument parsing / guard clauses, --dry-run plan output (text and secret
# redaction), the $DC gate (informational in dry-run, blocking before
# --apply), and that --apply without a required arg or against an
# unassigned DC never reaches a real `juju ssh` invocation. Does NOT and
# CANNOT validate real radosgw multisite behavior -- no live cluster exists
# this session (2026-07-10, prep-only).
# Exit: 0 all pass | 1 any case failed.  ASCII + LF.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT="$HERE/../../scripts/dc-dc-radosgw-multisite.sh"
PASS=0; FAIL=0

run() { # run <want_rc> <regex> <label> -- args...
  local want="$1" rx="$2" label="$3"; shift 3
  local out rc
  out="$(bash "$SCRIPT" "$@" 2>&1)"; rc=$?
  if [[ "$rc" == "$want" ]] && grep -qE "$rx" <<<"$out"; then
    echo "  PASS  $label"; PASS=$((PASS+1))
  else
    echo "  FAIL  $label (rc=$rc want=$want)"; echo "$out" | sed 's/^/        /'; FAIL=$((FAIL+1))
  fi
}
runnot() { # runnot <want_rc> <regex-must-NOT-appear> <label> -- args...
  local want="$1" rx="$2" label="$3"; shift 3
  local out rc
  out="$(bash "$SCRIPT" "$@" 2>&1)"; rc=$?
  if [[ "$rc" == "$want" ]] && ! grep -qE "$rx" <<<"$out"; then
    echo "  PASS  $label"; PASS=$((PASS+1))
  else
    echo "  FAIL  $label (rc=$rc want=$want, or forbidden pattern present)"; echo "$out" | sed 's/^/        /'; FAIL=$((FAIL+1))
  fi
}

# --- basic usage / arg parsing ---
run 1 'a subcommand is required'      "T1 no subcommand FAILS (rc 1)"
run 1 'unknown subcommand'            "T2 bogus subcommand FAILS (rc 1)" bogus
run 0 'usage:'                        "T3 --help exits 0 with usage" --help
run 1 '\-\-dc is required'            "T4 master-init missing --dc FAILS (rc 1)" master-init
run 1 '\-\-dc must be vr1-dc0 or vr1-dc1'     "T5 master-init bad --dc token FAILS" master-init --dc bogus --unit ceph-radosgw/0 --realm R --zonegroup ZG --zone Z --endpoint http://x:80
run 1 '\-\-unit is required'          "T6 master-init missing --unit FAILS" master-init --dc vr1-dc0
run 1 '\-\-realm is required'         "T7 master-init missing --realm FAILS" master-init --dc vr1-dc0 --unit ceph-radosgw/0 --zonegroup ZG --zone Z --endpoint http://x:80
run 1 '\-\-access-key is required'    "T8 join-readonly missing --access-key FAILS" join-readonly --dc vr1-dc0 --unit ceph-radosgw/0 --zonegroup ZG --zone Z --endpoint http://x:80 --secret S
run 1 '\-\-secret is required'        "T9 join-readonly missing --secret FAILS" join-readonly --dc vr1-dc0 --unit ceph-radosgw/0 --zonegroup ZG --zone Z --endpoint http://x:80 --access-key K
run 1 '\-\-zone is required'          "T10 enable-two-way missing --zone FAILS" enable-two-way --dc vr1-dc0 --unit ceph-radosgw/0

# --- dry-run plan content (dc1, gate OK) ---
MI_OUT="$(bash "$SCRIPT" master-init --dc vr1-dc0 --unit ceph-radosgw/0 --realm R --zonegroup ZG --zone Z1 --endpoint http://10.12.36.10:80 2>&1)"; MI_RC=$?
[[ "$MI_RC" == 0 ]] && grep -q 'OK (dry-run)' <<<"$MI_OUT" && { echo "  PASS  T11 master-init dry-run rc 0 + OK marker"; PASS=$((PASS+1)); } || { echo "  FAIL  T11"; FAIL=$((FAIL+1)); }
grep -q 'gate: OK (vr1-dc0)' <<<"$MI_OUT" && { echo "  PASS  T12 vr1-dc0 gate reports OK"; PASS=$((PASS+1)); } || { echo "  FAIL  T12"; FAIL=$((FAIL+1)); }
grep -qE 'realm create --rgw-realm=R' <<<"$MI_OUT" && grep -qE 'zonegroup create.*--master' <<<"$MI_OUT" && grep -qE 'zone create.*--master' <<<"$MI_OUT" && grep -q 'period update --commit' <<<"$MI_OUT" \
  && { echo "  PASS  T13 master-init plan contains realm/zonegroup/zone/period steps"; PASS=$((PASS+1)); } || { echo "  FAIL  T13"; echo "$MI_OUT" | sed 's/^/        /'; FAIL=$((FAIL+1)); }
grep -q 'no --restart-action given' <<<"$MI_OUT" && { echo "  PASS  T14 no-restart-action reminder present"; PASS=$((PASS+1)); } || { echo "  FAIL  T14"; FAIL=$((FAIL+1)); }

RESTART_OUT="$(bash "$SCRIPT" master-init --dc vr1-dc0 --unit ceph-radosgw/0 --realm R --zonegroup ZG --zone Z1 --endpoint http://x:80 --restart-action restart 2>&1)"
grep -qE 'juju run ceph-radosgw/0 restart -m openstack' <<<"$RESTART_OUT" && { echo "  PASS  T15 --restart-action adds a juju run step"; PASS=$((PASS+1)); } || { echo "  FAIL  T15"; echo "$RESTART_OUT" | sed 's/^/        /'; FAIL=$((FAIL+1)); }

# --- $DC gate: vr1-dc1 now passes (literals RATIFIED, D-124 amendment
# 2026-07-21); the reminder must surface DC1's OWN replication plane, never
# dc0's (cross-DC value surfacing). The gate's refusal path (exit 3) is
# retained as defense-in-depth but no longer CLI-reachable.
DC1_DRY="$(bash "$SCRIPT" master-init --dc vr1-dc1 --unit ceph-radosgw/0 --realm R --zonegroup ZG --zone Z1 --endpoint http://x:80 2>&1)"; DC1_DRY_RC=$?
[[ "$DC1_DRY_RC" == 0 ]] && grep -q 'gate: OK (vr1-dc1)' <<<"$DC1_DRY" && grep -q 'OK (dry-run)' <<<"$DC1_DRY" \
  && { echo "  PASS  T16 dc1 dry-run prints the plan (gate OK, D-124 ratified)"; PASS=$((PASS+1)); } || { echo "  FAIL  T16"; echo "$DC1_DRY" | sed 's/^/        /'; FAIL=$((FAIL+1)); }
grep -q 'REPLICATION plane (10.12.84.0/22' <<<"$DC1_DRY" \
  && { echo "  PASS  T16b dc1 reminder shows dc1's OWN replication CIDR (not dc0's)"; PASS=$((PASS+1)); } || { echo "  FAIL  T16b (cross-DC value surfaced)"; echo "$DC1_DRY" | sed 's/^/        /'; FAIL=$((FAIL+1)); }

if command -v juju >/dev/null 2>&1; then
  echo "  SKIP  T17 juju-missing case (juju IS present in this environment -- can't exercise the missing-tool guard here)"
else
  run 2 'juju required on PATH' "T17 dc1 --apply passes the gate, FAILS on missing juju (rc 2)" master-init --dc vr1-dc1 --unit ceph-radosgw/0 --realm R --zonegroup ZG --zone Z1 --endpoint http://x:80 --apply
fi

# --- secret redaction ---
JR_OUT="$(bash "$SCRIPT" join-readonly --dc vr1-dc0 --unit ceph-radosgw/0 --zonegroup ZG --zone Z2 --endpoint http://x:80 --access-key AK123 --secret TOPSECRETVALUE 2>&1)"
grep -q '<REDACTED>' <<<"$JR_OUT" && ! grep -q 'TOPSECRETVALUE' <<<"$JR_OUT" \
  && { echo "  PASS  T18 --secret value is redacted in printed plan"; PASS=$((PASS+1)); } || { echo "  FAIL  T18 (secret leaked or not redacted)"; echo "$JR_OUT" | sed 's/^/        /'; FAIL=$((FAIL+1)); }

# --- --apply gate: never executes without --apply; blocked when juju missing (dc1, gate OK) ---
if command -v juju >/dev/null 2>&1; then
  echo "  SKIP  T19 juju-missing case (juju IS present in this environment -- can't exercise the missing-tool guard here)"
else
  run 2 'juju required on PATH' "T19 --apply with dc1 (gate OK) but juju absent FAILS (rc 2)" master-init --dc vr1-dc0 --unit ceph-radosgw/0 --realm R --zonegroup ZG --zone Z1 --endpoint http://x:80 --apply
fi

echo; echo "RESULT: PASS=$PASS FAIL=$FAIL"
[[ "$FAIL" -eq 0 ]] && { echo "ALL PASS"; exit 0; } || exit 1
