#!/usr/bin/env bash
# Zero-dependency tests for ccr-up.sh. Hermetic: every test overrides CCR_PORT (high range) + CCR_CMD
# (a fake daemon), so the REAL ccr and the REAL port 3456 are NEVER touched. All fakes live under one
# temp dir; the sweeper kills anything referencing it. Run: bash test-ccr-up.sh
set -uo pipefail
LIB="$(cd "$(dirname "$0")" && pwd)/ccr-up.sh"
PASS=0 FAIL=0
ok()  { printf '  ok   %s\n' "$1"; PASS=$((PASS + 1)); }
bad() { printf '  FAIL %s\n     %s\n' "$1" "${2:-}"; FAIL=$((FAIL + 1)); }

TMPD=$(mktemp -d)
jfield() { python3 -c "import json,sys; print(json.load(sys.stdin)$1)" 2>/dev/null; }

# Kill every fake we spawned (they all live under TMPD), free the lock/log files.
sweep() {
  pkill -f "$TMPD" >/dev/null 2>&1
  for pf in "$TMPD"/*.pid; do [[ -f "$pf" ]] && kill "$(cat "$pf")" >/dev/null 2>&1; done
  rm -f /tmp/ccr-345*.lock /tmp/ccr-cu-*.log 2>/dev/null
}
trap 'sweep; rm -rf "$TMPD"' EXIT

# ── fakes ─────────────────────────────────────────────────────────────────────
# bind: a real listener curl -sf answers (http.server returns 200 on /).
cat > "$TMPD/bind.sh" <<EOF
#!/usr/bin/env bash
echo \$\$ > "$TMPD/bind.\$1.pid"
exec python3 -m http.server "\$1" --bind 127.0.0.1
EOF
# delayed: comes up after ~1s (proves the readiness poll catches a late bind).
cat > "$TMPD/delayed.sh" <<EOF
#!/usr/bin/env bash
sleep 1
echo \$\$ > "$TMPD/delayed.\$1.pid"
exec python3 -m http.server "\$1" --bind 127.0.0.1
EOF
# noop: exits immediately, never binds (proves bounded fail, no hang).
cat > "$TMPD/noop.sh" <<'EOF'
#!/usr/bin/env bash
exit 0
EOF
# spew: NEVER exits, floods stdout forever (the 46-min-hang shape). Must not block the caller.
cat > "$TMPD/spew.sh" <<EOF
#!/usr/bin/env bash
echo \$\$ > "$TMPD/spew.pid"
while true; do echo "SPAM-this-would-have-hung-the-run"; done
EOF
# counter+bind: records each launch (single-flight proof), then binds after a beat.
cat > "$TMPD/counter.sh" <<EOF
#!/usr/bin/env bash
echo x >> "$TMPD/launches"
sleep 1
echo \$\$ > "$TMPD/counter.\$1.pid"
exec python3 -m http.server "\$1" --bind 127.0.0.1
EOF
chmod +x "$TMPD"/*.sh

echo "ccr-up tests:"

# 1) already-up: a listener is already on the port → up=true, NOTHING launched (counter stays empty).
PORT=34560
python3 -m http.server "$PORT" --bind 127.0.0.1 >/dev/null 2>&1 &
PRE=$!
for _ in $(seq 1 20); do curl -sf "127.0.0.1:$PORT" >/dev/null 2>&1 && break; sleep 0.1; done
rm -f "$TMPD/launches"
j=$(CCR_PORT=$PORT CCR_CMD="bash $TMPD/counter.sh $PORT" CCR_UP_TIMEOUT=3 bash "$LIB" cu-1)
kill "$PRE" >/dev/null 2>&1
[[ "$(printf '%s' "$j" | jfield "['up']")" == "True" && ! -f "$TMPD/launches" ]] \
  && ok "already-up: up=true, launches nothing (idempotent)" \
  || bad "already-up" "j=$j launches=$([[ -f $TMPD/launches ]] && echo PRESENT || echo absent)"

# 2) binary-missing: distinct, debuggable detail (not a generic timeout).
j=$(CCR_PORT=34561 CCR_CMD="definitely_not_a_real_binary_xyz start" CCR_UP_TIMEOUT=2 bash "$LIB" cu-2)
[[ "$(printf '%s' "$j" | jfield "['up']")" == "False" && "$(printf '%s' "$j" | jfield "['detail']")" == *"binary not found"* ]] \
  && ok "binary-missing: up=false, detail names the missing binary" \
  || bad "binary-missing" "j=$j"

# 3) launch-then-ready: daemon binds after ~1s → poll catches it → up=true.
j=$(CCR_PORT=34562 CCR_CMD="bash $TMPD/delayed.sh 34562" CCR_UP_TIMEOUT=10 bash "$LIB" cu-3)
[[ "$(printf '%s' "$j" | jfield "['up']")" == "True" ]] \
  && ok "launch-then-ready: poll catches a late bind, up=true" \
  || bad "launch-then-ready" "j=$j"

# 4) never-ready: bounded fail. up=false AND the call returns well within timeout+slack (no hang).
t0=$SECONDS
j=$(CCR_PORT=34563 CCR_CMD="bash $TMPD/noop.sh" CCR_UP_TIMEOUT=2 bash "$LIB" cu-4)
dt=$((SECONDS - t0))
[[ "$(printf '%s' "$j" | jfield "['up']")" == "False" && $dt -lt 6 ]] \
  && ok "never-ready: up=false, bounded (~${dt}s, no hang)" \
  || bad "never-ready" "j=$j dt=${dt}s"

# 5) NON-BLOCKING TEETH: a daemon that spews forever and never exits must NOT block the caller.
#    Outer `timeout 8` guards the whole call: exit 124 = the script hung. We require exit 0 AND a
#    clean parseable JSON line (a chatty daemon sharing the fd would interleave garbage).
out=$(CCR_PORT=34564 CCR_CMD="bash $TMPD/spew.sh" CCR_UP_TIMEOUT=2 timeout 8 bash "$LIB" cu-5)
rc=$?
clean=$(printf '%s' "$out" | jfield "['up']")
[[ $rc -ne 124 && "$clean" == "False" ]] \
  && ok "non-blocking: forever-spewing daemon does NOT hang the caller, JSON clean (rc=$rc)" \
  || bad "non-blocking" "rc=$rc out=$out"

# 5b) VERIFY-NEGATIVE: a de-fanged copy that runs the launch in the FOREGROUND (the historical bug)
#     MUST hang under the same guard → exit 124. If flipping it doesn't go red, test 5 proves nothing.
sed 's/ & disown//' "$LIB" > "$TMPD/blocking.sh"
CCR_PORT=34565 CCR_CMD="bash $TMPD/spew.sh" CCR_UP_TIMEOUT=2 timeout 8 bash "$TMPD/blocking.sh" cu-5b >/dev/null 2>&1
nrc=$?
[[ $nrc -eq 124 ]] \
  && ok "verify-negative: foreground launch DOES hang (rc=124) — test 5 has teeth" \
  || bad "verify-negative (foreground should hang)" "nrc=$nrc (expected 124)"

# 6) LOCK NOT INHERITED: after a launch backgrounds a long-lived daemon, the single-flight lock must
#    be FREE (daemon closed fd 9 via 9>&-). If it inherited the lock, the next caller deadlocks.
CCR_PORT=34566 CCR_CMD="bash $TMPD/bind.sh 34566" CCR_UP_TIMEOUT=8 bash "$LIB" cu-6 >/dev/null 2>&1
( flock -n -w 2 8 || exit 9 ) 8>"/tmp/ccr-34566.lock"
lrc=$?
[[ $lrc -eq 0 ]] \
  && ok "lock-not-inherited: daemon does not hold the lock (re-acquirable, no deadlock)" \
  || bad "lock-not-inherited" "could not re-acquire lock (rc=$lrc) — daemon inherited fd 9"

# 7) SINGLE-FLIGHT (TOCTOU): two callers race on a DOWN port; only ONE launch may fire.
rm -f "$TMPD/launches"
( CCR_PORT=34567 CCR_CMD="bash $TMPD/counter.sh 34567" CCR_UP_TIMEOUT=8 bash "$LIB" cu-7a >/dev/null 2>&1 ) &
( CCR_PORT=34567 CCR_CMD="bash $TMPD/counter.sh 34567" CCR_UP_TIMEOUT=8 bash "$LIB" cu-7b >/dev/null 2>&1 ) &
wait
n=$(wc -l < "$TMPD/launches" 2>/dev/null | tr -d ' ')
[[ "$n" == "1" ]] \
  && ok "single-flight: concurrent callers launch ccr exactly once (n=$n)" \
  || bad "single-flight" "launch count n=$n (expected 1)"

echo
printf 'PASS=%d FAIL=%d\n' "$PASS" "$FAIL"
[[ $FAIL -eq 0 ]]
