#!/usr/bin/env bash
# Tests para supervise_fleetview_tui. Usa un binario falso (un script) que cuenta
# sus invocaciones, para verificar respawn, crash-loop guard y sentinel sin correr
# la TUI real.
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/supervise_fleetview_tui.sh"

PASS=0
FAIL=0

assert_contains() {
    local test_name="$1" needle="$2" haystack="$3"
    if echo "$haystack" | grep -qF "$needle"; then
        echo "PASS: $test_name"
        PASS=$((PASS+1))
    else
        echo "FAIL: $test_name — expected to contain '$needle'"
        echo "      got: $haystack"
        FAIL=$((FAIL+1))
    fi
}

assert_eq() {
    local test_name="$1" expected="$2" actual="$3"
    if [[ "$actual" == "$expected" ]]; then
        echo "PASS: $test_name ($actual)"
        PASS=$((PASS+1))
    else
        echo "FAIL: $test_name — expected '$expected', got '$actual'"
        FAIL=$((FAIL+1))
    fi
}

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
COUNTER="$TMP/runs"
SENTINEL="$TMP/sentinel"

# --- Test 1 (crash-loop guard): binario que sale rapido siempre se rinde a las N ---
# Fake bin: registra una linea por invocacion y sale 1 inmediato.
FAKE_FAST="$TMP/fake_fast.sh"
cat > "$FAKE_FAST" <<EOF
#!/usr/bin/env bash
echo run >> "$COUNTER"
exit 1
EOF
chmod +x "$FAKE_FAST"

: > "$COUNTER"
set +e
out=$(supervise_fleetview_tui --bin "$FAKE_FAST" --backoff 0 --min-uptime 100 \
        --max-fast-exits 3 --sentinel "$SENTINEL" 2>&1); rc=$?
set -e
runs=$(wc -l < "$COUNTER" | tr -d ' ')
assert_eq       "crash-loop: se rinde con rc=3"           3 "$rc"
assert_eq       "crash-loop: corrio exactamente 3 veces"  3 "$runs"
assert_contains "crash-loop: mensaje de rendicion"        "el supervisor se rinde" "$out"

# --- Test 2 (golden respawn + sentinel): relanza tras salir, para via sentinel ---
# Fake bin: en la 2a invocacion crea el sentinel, luego sale. Prueba que:
#   (a) tras la 1a salida RELANZA (respawn) -> hay 2a invocacion (golden).
#   (b) al ver el sentinel, PARA (no hay 3a invocacion).
FAKE_SENT="$TMP/fake_sent.sh"
cat > "$FAKE_SENT" <<EOF
#!/usr/bin/env bash
echo run >> "$COUNTER"
n=\$(wc -l < "$COUNTER" | tr -d ' ')
if [[ "\$n" -ge 2 ]]; then
    touch "$SENTINEL"
fi
exit 1
EOF
chmod +x "$FAKE_SENT"

: > "$COUNTER"
rm -f "$SENTINEL"
set +e
out=$(supervise_fleetview_tui --bin "$FAKE_SENT" --backoff 0 --min-uptime 0 \
        --max-fast-exits 99 --sentinel "$SENTINEL" 2>&1); rc=$?
set -e
runs=$(wc -l < "$COUNTER" | tr -d ' ')
assert_eq       "golden: relanzo tras morir (2 invocaciones)" 2 "$runs"
assert_eq       "sentinel: para limpio con rc=0"              0 "$rc"
assert_contains "sentinel: mensaje de parada voluntaria"      "parada solicitada via sentinel" "$out"
assert_eq       "sentinel: el fichero se consume (borrado)"   "no" "$([[ -f "$SENTINEL" ]] && echo si || echo no)"
assert_contains "golden: registra el respawn"                 "relanzando" "$out"

# --- Test 3 (error): falta --bin ---
set +e
out=$(supervise_fleetview_tui --backoff 0 2>&1); rc=$?
set -e
assert_eq       "error: sin --bin devuelve rc=1" 1 "$rc"
assert_contains "error: mensaje falta --bin"     "falta --bin" "$out"

# --- Test 4 (error): binario no ejecutable ---
set +e
out=$(supervise_fleetview_tui --bin "$TMP/no_existe" 2>&1); rc=$?
set -e
assert_eq       "error: binario no ejecutable rc=1" 1 "$rc"
assert_contains "error: mensaje no ejecutable"      "no es ejecutable" "$out"

echo "---"
echo "Results: $PASS passed, $FAIL failed"
[[ $FAIL -eq 0 ]] || exit 1
