#!/usr/bin/env bash
# Tests para fleet_send_text. Levanta un socket tmux PROPIO de test
# (fleet_test_<pid>, nunca el socket "fleet" real) con un pane `cat` vivo, y
# verifica: envio + verificacion via capture-pane (golden), supervivencia al
# focus-swap (break-pane preserva el pane_id), resolucion por sessionId fake,
# y los paths de error/guard. No toca la flota real ni ningun agente.
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/fleet_send_text.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_not_contains() {
    local test_name="$1" needle="$2" haystack="$3"
    if echo "$haystack" | grep -qF "$needle"; then
        echo "FAIL: $test_name — should NOT contain '$needle'"
        echo "      got: $haystack"
        FAIL=$((FAIL+1))
    else
        echo "PASS: $test_name"
        PASS=$((PASS+1))
    fi
}

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

command -v tmux >/dev/null 2>&1 || { echo "SKIP: tmux no instalado"; exit 0; }

# --- Socket de test PROPIO + pane `cat` vivo (con echo de tty) ---
SOCK="fleet_test_$$"
TMP="$(mktemp -d)"
SESS="$TMP/sessions"
mkdir -p "$SESS"

cleanup() {
    tmux -L "$SOCK" kill-server 2>/dev/null || true
    rm -rf "$TMP"
}
trap cleanup EXIT

tmux -L "$SOCK" new-session -d -s t -x 120 -y 30 'cat'
sleep 0.4

PANE_PID="$(tmux -L "$SOCK" list-panes -a -F '#{pane_pid}' | head -n1)"
PANE_ID0="$(tmux -L "$SOCK" list-panes -a -F '#{pane_pid} #{pane_id}' | awk -v p="$PANE_PID" '$1==p{print $2}')"
WIN_ID0="$(tmux -L "$SOCK" list-panes -a -F '#{pane_pid} #{window_id}' | awk -v p="$PANE_PID" '$1==p{print $2}')"
echo "INFO: socket=$SOCK pane_pid=$PANE_PID pane_id=$PANE_ID0 window_id=$WIN_ID0"

# self_pid forzado a un PID que nunca sera target en los tests golden.
export FN_FLEET_SELF_PID=1
export FN_FLEET_SESSIONS_DIR="$SESS"

# --- Test 1 (golden): enviar por PID, verificar via capture-pane ---
set +e
out=$(fleet_send_text "$PANE_PID" "HOLA_FLEET_123" --socket "$SOCK" --no-enter --retries 1 2>&1); rc=$?
set -e
assert_rc       "golden: envio por PID sale 0" 0 "$rc"
assert_contains "golden: reporta status=ok"   "status=ok" "$out"
assert_contains "golden: reporta el pane_id estable" "pane=$PANE_ID0" "$out"
cap="$(tmux -L "$SOCK" capture-pane -p -t "$PANE_ID0")"
assert_contains "golden: el texto llego al pane (capture-pane)" "HOLA_FLEET_123" "$cap"

# limpiar input del cat
tmux -L "$SOCK" send-keys -t "$PANE_ID0" C-u; sleep 0.2
tmux -L "$SOCK" send-keys -t "$PANE_ID0" C-l 2>/dev/null || true; sleep 0.2

# --- Test 2 (edge focus-swap): mover el pane a otra window, pane_id NO migra ---
# Anadimos un segundo pane para poder break-pane el nuestro a una window nueva.
tmux -L "$SOCK" split-window -t "$WIN_ID0" -d 'cat'; sleep 0.3
tmux -L "$SOCK" break-pane -d -s "$PANE_ID0"; sleep 0.3
WIN_ID1="$(tmux -L "$SOCK" list-panes -a -F '#{pane_pid} #{window_id}' | awk -v p="$PANE_PID" '$1==p{print $2}')"
PANE_ID1="$(tmux -L "$SOCK" list-panes -a -F '#{pane_pid} #{pane_id}' | awk -v p="$PANE_PID" '$1==p{print $2}')"
echo "INFO: tras break-pane: pane_id=$PANE_ID1 (era $PANE_ID0) window_id=$WIN_ID1 (era $WIN_ID0)"
assert_contains "edge: pane_id NO cambia tras mover de window" "$PANE_ID0" "$PANE_ID1"

set +e
out=$(fleet_send_text "$PANE_PID" "TRAS_MOVER_456" --socket "$SOCK" --no-enter --retries 1 2>&1); rc=$?
set -e
assert_rc       "edge: reenvio tras focus-swap sale 0" 0 "$rc"
cap="$(tmux -L "$SOCK" capture-pane -p -t "$PANE_ID1")"
assert_contains "edge: el texto sigue llegando tras mover de window" "TRAS_MOVER_456" "$cap"
tmux -L "$SOCK" send-keys -t "$PANE_ID1" C-u; sleep 0.2

# --- Test 3 (edge): resolver por sessionId (sessions/<pid>.json fake) ---
echo "{\"sessionId\":\"test-sid-aaa-111\",\"cwd\":\"/tmp/x\"}" > "$SESS/$PANE_PID.json"
set +e
out=$(fleet_send_text "test-sid-aaa" "VIA_SID_789" --socket "$SOCK" --no-enter --retries 1 2>&1); rc=$?
set -e
assert_rc       "edge: resolucion por prefijo de sessionId sale 0" 0 "$rc"
cap="$(tmux -L "$SOCK" capture-pane -p -t "$PANE_ID1")"
assert_contains "edge: texto llego resolviendo por sessionId" "VIA_SID_789" "$cap"
tmux -L "$SOCK" send-keys -t "$PANE_ID1" C-u; sleep 0.2

# --- Test 4 (edge): --dry-run no envia nada ---
set +e
out=$(fleet_send_text "$PANE_PID" "NO_DEBE_APARECER_000" --socket "$SOCK" --no-enter --dry-run 2>&1); rc=$?
set -e
assert_rc       "edge: dry-run sale 0" 0 "$rc"
assert_contains "edge: dry-run reporta status=dry-run" "status=dry-run" "$out"
cap="$(tmux -L "$SOCK" capture-pane -p -t "$PANE_ID1")"
assert_not_contains "edge: dry-run NO inyecto texto" "NO_DEBE_APARECER_000" "$cap"

# --- Test 5 (error): sessionId que no resuelve a PID -> rc 2 ---
set +e
out=$(fleet_send_text "sid-inexistente-zzz" "x" --socket "$SOCK" 2>&1); rc=$?
set -e
assert_rc       "error: sessionId no resuelto sale 2" 2 "$rc"
assert_contains "error: mensaje de target no resuelto" "no se pudo resolver" "$out"

# --- Test 6 (error): falta el texto -> rc 2 ---
set +e
out=$(fleet_send_text "$PANE_PID" --socket "$SOCK" 2>&1); rc=$?
set -e
assert_rc       "error: falta texto sale 2" 2 "$rc"

# --- Test 7 (guard anti-self): target == self_pid -> rc 3 ---
set +e
out=$(FN_FLEET_SELF_PID="$PANE_PID" fleet_send_text "$PANE_PID" "x" --socket "$SOCK" 2>&1); rc=$?
set -e
assert_rc       "guard: enviar a la sesion actual sale 3" 3 "$rc"
assert_contains "guard: mensaje anti-self" "No me autoenvio" "$out"

# --- Test 8 (error): PID sin pane vivo -> rc 4 ---
set +e
out=$(fleet_send_text 999999 "x" --socket "$SOCK" 2>&1); rc=$?
set -e
assert_rc       "error: PID sin pane vivo sale 4" 4 "$rc"
assert_contains "error: mensaje no pane vivo" "no se encontro un pane vivo" "$out"

# --- Resumen ---
echo ""
echo "================================"
echo "PASS: $PASS  FAIL: $FAIL"
echo "================================"
[[ "$FAIL" -eq 0 ]]
