#!/usr/bin/env bash
# tests/phase-06-mgmt-vm/run-tests.sh -- offline regression for phase-06-mgmt-vm.sh
# + unit tests of resolve_tenant_ip.py. Fake openstack; real python3.
set -euo pipefail
IFS=$'\n\t'
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPTS="$(cd "$HERE/../../scripts" && pwd)"
TARGET="$SCRIPTS/phase-06-mgmt-vm.sh"
RESOLVE="$SCRIPTS/resolve_tenant_ip.py"
BIN="$HERE/fakebin"
[ -f "$TARGET" ] && [ -f "$RESOLVE" ] || { echo "FAIL: target/helper missing" >&2; exit 1; }
chmod +x "$BIN"/* 2>/dev/null || true
WORK="$(mktemp -d)"; trap 'rm -rf "$WORK"' EXIT
rc_all=0

echo "=== unit: resolve_tenant_ip.py (FIP via env; three address shapes) ==="
u() { local want="$1" fip="$2" json="$3" label="$4" got
  got=$(printf '%s' "$json" | FIP="$fip" python3 "$RESOLVE")
  if [ "$got" = "$want" ]; then printf '  [OK]  %-30s -> %s\n' "$label" "${got:-<empty>}"
  else printf '  [XX]  %-30s -> %s (want %s)\n' "$label" "${got:-<empty>}" "$want"; rc_all=1; fi
}
u 10.20.0.107 10.12.5.103 '{"addresses":{"n":["10.20.0.107","10.12.5.103"]}}'                   "list shape"
u 10.20.0.107 10.12.5.103 '{"addresses":{"n":[{"addr":"10.20.0.107"},{"addr":"10.12.5.103"}]}}' "dict {addr} shape"
u 10.20.0.107 10.12.5.103 '{"addresses":{"n":"10.20.0.107, 10.12.5.103"}}'                       "comma-string shape"
u ""          10.12.5.103 '{"addresses":{"n":["10.12.5.103"]}}'                                   "only FIP -> empty"
u 10.20.0.107 ""          '{"addresses":{"n":["10.20.0.107"]}}'                                   "no FIP env -> first"

echo "=== integration: phase-06-mgmt-vm.sh ==="
run() {
  local want="$1" re="$2" label="$3"; shift 3
  rm -f "$WORK/vm.marker" "$WORK/deleted.marker" "$WORK/recreated.marker" "$WORK/net.env"
  local rc
  set +e
  PATH="$BIN:$PATH" HOME="$WORK" OS_AUTH_URL=x ENVFILE="$WORK/net.env" \
    MK_VM="$WORK/vm.marker" MK_DELETED="$WORK/deleted.marker" MK_RECREATED="$WORK/recreated.marker" \
    POLL_TRIES=2 POLL_SLEEP=0 FIPVAL=10.12.5.103 TENANT=10.20.0.107 \
    env "$@" bash "$TARGET" >"$WORK/out" 2>&1
  rc=$?; set -e
  if [ "$rc" -eq "$want" ] && grep -qE "$re" "$WORK/out"; then
    printf '  [OK]  %-44s exit %s\n' "$label" "$rc"
  else
    printf '  [XX]  %-44s exit %s (want %s; /%s/)\n' "$label" "$rc" "$want" "$re"
    sed 's/^/        /' "$WORK/out"; rc_all=1
  fi
}
run 0 'allocated . associated FIP 10.12.5.103' "fresh: re-scope+create+allocate FIP"
run 0 'already has floating IP 10.12.5.103 .reusing.' "idempotent: reuse existing FIP" VM_PRESENT=1 FIP_PRESENT=1
run 1 'entered ERROR'                          "fresh VM -> ERROR abort"       VM_STATUS=ERROR
run 1 'not ACTIVE after'                       "VM never ACTIVE -> abort"      VM_STATUS=BUILD
run 1 'could not resolve tenant IP'            "tenant unresolvable -> abort"  VM_PRESENT=1 FIP_PRESENT=1 ADDR_ONLY_FIP=1
run 2 'OS_AUTH_URL unset'                      "precondition: no auth -> exit 2" OS_AUTH_URL=
run 2 'cannot scope a token to project'        "re-scope denied -> exit 2"     SCOPE_FAIL=1
run 2 'keypair capi-mgmt-key not visible'      "keypair not visible -> exit 2" KP_VIS=0
run 2 'security group capi-mgmt-sg not visible' "sg not visible -> exit 2"     SG_VIS=0
run 2 'network capi-mgmt-net not visible'      "network not visible -> exit 2" NET_VIS=0
run 1 'exists in ERROR state'                  "existing ERROR, default -> abort" VM_PRESENT=1 VM_STATUS=ERROR
run 0 'recreated'                              "existing ERROR + RECREATE=1 -> ok" VM_PRESENT=1 VM_STATUS=ERROR RECREATE_ON_ERROR=1

echo "=== assert: net.env persisted (both keys) + mode 600 ==="
rm -f "$WORK/vm.marker" "$WORK/deleted.marker" "$WORK/recreated.marker" "$WORK/net.env"
PATH="$BIN:$PATH" HOME="$WORK" OS_AUTH_URL=x ENVFILE="$WORK/net.env" MK_VM="$WORK/vm.marker" \
  MK_DELETED="$WORK/deleted.marker" MK_RECREATED="$WORK/recreated.marker" \
  POLL_TRIES=2 POLL_SLEEP=0 FIPVAL=10.12.5.103 TENANT=10.20.0.107 bash "$TARGET" >/dev/null 2>&1 || true
if grep -q '^MGMT_FIP=10.12.5.103$' "$WORK/net.env" && grep -q '^MGMT_TENANT_IP=10.20.0.107$' "$WORK/net.env"; then
  perm=$(stat -c '%a' "$WORK/net.env" 2>/dev/null || echo '?')
  [ "$perm" = 600 ] && echo "  [OK] net.env has both keys, mode 600" || { echo "  [XX] net.env mode=$perm (want 600)"; rc_all=1; }
else
  echo "  [XX] net.env missing keys"; rc_all=1
fi
echo
[ "$rc_all" -eq 0 ] && echo "ALL PASS" || echo "SOME FAILED"
exit "$rc_all"
