#!/usr/bin/env bash
# Tests for otmux — OOSH tmux wrapper
# Tests: pane.capture, send, pane.lock, pane.title, tree, tree.detailed

level=$1
if [ -z "$level" ]; then
  level=1
fi
echo "starting: ${BASH_SOURCE[@]##*/} <LOG_LEVEL=$level>"

source this
source test.suite

log.level $level

# ============================================================================
# T1: otmux function exists
# ============================================================================
test.case $level "otmux is callable" \
  which otmux

if which otmux &>/dev/null; then
  expect.pass "otmux found on PATH"
else
  expect.fail "otmux should be on PATH"
fi

# ============================================================================
# T2: otmux tree lists sessions
# ============================================================================
test.case $level "otmux tree lists sessions" \
  otmux tree

TREE_OUTPUT=$(otmux tree 2>/dev/null)
if [ -n "$TREE_OUTPUT" ]; then
  expect.pass "otmux tree produced output"
else
  expect.fail "otmux tree should list tmux sessions"
fi

# ============================================================================
# T3: otmux tree.detailed lists sessions with agent info
# ============================================================================
test.case $level "otmux tree.detailed lists sessions with agent info" \
  otmux tree.detailed

DETAILED_OUTPUT=$(otmux tree.detailed 2>/dev/null)
if [ -n "$DETAILED_OUTPUT" ]; then
  expect.pass "otmux tree.detailed produced output"
else
  expect.fail "otmux tree.detailed should list sessions with agent info"
fi

# ============================================================================
# T4: otmux pane.capture captures pane content
# ============================================================================
# Use a fixture session with known content
# Note: runs before source otmux, so $TMUX_CMD unavailable — use tmux directly
TEST_CAPTURE_SESS="__test_capture_$$"
tmux new-session -d -s "$TEST_CAPTURE_SESS" 2>/dev/null
T4_FIXTURE_OK=$?

if [ "$T4_FIXTURE_OK" -eq 0 ]; then
  # Dynamically detect first pane address (respects base-index config)
  FIRST_PANE=$(tmux list-panes -t "$TEST_CAPTURE_SESS" -F "#{session_name}:#{window_index}.#{pane_index}" 2>/dev/null | head -1)

  tmux send-keys -t "$FIRST_PANE" "echo CAPTURE_MARKER_$$" Enter
  sleep 0.3

  test.case $level "otmux pane.capture captures content" \
    otmux pane.capture "$FIRST_PANE" 200

  CAPTURE_OUTPUT=$(otmux pane.capture "$FIRST_PANE" 200 2>/dev/null)
  if echo "$CAPTURE_OUTPUT" | grep -q "CAPTURE_MARKER_$$"; then
    expect.pass "pane.capture returned content from $FIRST_PANE"
  else
    expect.fail "pane.capture should return content from $FIRST_PANE"
  fi

  tmux kill-session -t "$TEST_CAPTURE_SESS" 2>/dev/null
else
  test.case $level "otmux pane.capture (skipped - no tmux)" \
    echo "skipped"
  expect.pass "pane.capture test skipped (tmux unavailable)"
fi

# ============================================================================
# T5: otmux.send function defined in script
# ============================================================================
test.case $level "otmux.send function defined in script" \
  grep -q "^otmux.send()" "$OOSH_DIR/otmux"

if grep -q "^otmux.send()" "$OOSH_DIR/otmux"; then
  expect.pass "otmux.send function defined"
else
  expect.fail "otmux.send should be defined in otmux script"
fi

# ============================================================================
# T6: otmux.pane.title function defined in script
# ============================================================================
test.case $level "otmux.pane.title function defined in script" \
  grep -q "^otmux.pane.title()" "$OOSH_DIR/otmux"

if grep -q "^otmux.pane.title()" "$OOSH_DIR/otmux"; then
  expect.pass "otmux.pane.title function defined"
else
  expect.fail "otmux.pane.title should be defined in otmux script"
fi

# ============================================================================
# T7: otmux.pane.lock function defined in script
# ============================================================================
test.case $level "otmux.pane.lock function defined in script" \
  grep -q "^otmux.pane.lock()" "$OOSH_DIR/otmux"

if grep -q "^otmux.pane.lock()" "$OOSH_DIR/otmux"; then
  expect.pass "otmux.pane.lock function defined"
else
  expect.fail "otmux.pane.lock should be defined in otmux script"
fi

# ============================================================================
# T8: otmux.send.enter function defined in script
# ============================================================================
test.case $level "otmux.send.enter function defined in script" \
  grep -q "^otmux.send.enter()" "$OOSH_DIR/otmux"

if grep -q "^otmux.send.enter()" "$OOSH_DIR/otmux"; then
  expect.pass "otmux.send.enter function defined"
else
  expect.fail "otmux.send.enter should be defined in otmux script"
fi

# ============================================================================
# T9: otmux setup.default runs without error
# ============================================================================
test.case $level "T9: setup.default runs without error" \
  otmux setup.default

create.result $RETURN_VALUE "ran"
expect 0 "ran" "setup.default should exit 0"

# ============================================================================
# T10: setup.default sets pane-border-status to top
# ============================================================================
test.case $level "T10: pane-border-status is top after setup.default" \
  tmux show-option -gv pane-border-status

BORDER_STATUS=$(tmux show-option -gv pane-border-status 2>/dev/null)
if [ "$BORDER_STATUS" = "top" ]; then
  create.result 0 "top"
else
  create.result 1 "$BORDER_STATUS"
fi
expect 0 "top" "pane-border-status should be top"

# ============================================================================
# T11: setup.default enables mouse
# ============================================================================
test.case $level "T11: mouse is on after setup.default" \
  tmux show-option -gv mouse

MOUSE=$(tmux show-option -gv mouse 2>/dev/null)
if [ "$MOUSE" = "on" ]; then
  create.result 0 "on"
else
  create.result 1 "$MOUSE"
fi
expect 0 "on" "mouse should be on"

# ============================================================================
# T12: setup.default sets vi mode-keys
# ============================================================================
test.case $level "T12: mode-keys is vi after setup.default" \
  tmux show-window-option -gv mode-keys

MODE_KEYS=$(tmux show-window-option -gv mode-keys 2>/dev/null)
if [ "$MODE_KEYS" = "vi" ]; then
  create.result 0 "vi"
else
  create.result 1 "$MODE_KEYS"
fi
expect 0 "vi" "mode-keys should be vi"

# ============================================================================
# T13: setup.default configures clipboard bindings
# ============================================================================
test.case $level "T13: clipboard copy-mode-vi y binding exists" \
  tmux list-keys -T copy-mode-vi

CLIPBOARD_BINDING=$(tmux list-keys -T copy-mode-vi 2>/dev/null | grep "copy-pipe-and-cancel")
if [ -n "$CLIPBOARD_BINDING" ]; then
  create.result 0 "bound"
else
  create.result 1 "missing"
fi
expect 0 "bound" "copy-mode-vi should have copy-pipe-and-cancel binding"

# ============================================================================
# T14: setup.default sets history-limit to 50000
# ============================================================================
test.case $level "T14: history-limit is 50000 after setup.default" \
  tmux show-option -gv history-limit

HIST_LIMIT=$(tmux show-option -gv history-limit 2>/dev/null)
if [ "$HIST_LIMIT" = "50000" ]; then
  create.result 0 "50000"
else
  create.result 1 "$HIST_LIMIT"
fi
expect 0 "50000" "history-limit should be 50000"

# ============================================================================
# T15: setup.default function defined in script
# ============================================================================
test.case $level "T15: otmux.setup.default function defined" \
  grep -q "^otmux.setup.default()" "$OOSH_DIR/otmux"

if grep -q "^otmux.setup.default()" "$OOSH_DIR/otmux"; then
  create.result 0 "defined"
else
  create.result 1 "missing"
fi
expect 0 "defined" "otmux.setup.default should be defined in otmux script"

# ============================================================================
# DRY parameter.completion tests (commit a79b85e)
# ============================================================================

# Source otmux so we can call completion functions directly
source "$OOSH_DIR/otmux"

# ============================================================================
# T16: parameter.completion.target returns directions + panes
# ============================================================================
test.case $level "T16: parameter.completion.target returns directions and panes" \
  otmux.parameter.completion.target

TARGET_OUT=$(otmux.parameter.completion.target 2>/dev/null)
HAS_DIRS=true
for d in U D L R; do
  echo "$TARGET_OUT" | grep -qx "$d" || HAS_DIRS=false
done
HAS_PANES=$(echo "$TARGET_OUT" | grep -c ':' || true)

if $HAS_DIRS && [ "$HAS_PANES" -gt 0 ]; then
  create.result 0 "directions+panes"
else
  create.result 1 "dirs=$HAS_DIRS panes=$HAS_PANES"
fi
expect 0 "directions+panes" "target completion should return U/D/L/R and pane addresses"

# ============================================================================
# T17: parameter.completion.sourcePane returns pane addresses
# ============================================================================
test.case $level "T17: parameter.completion.sourcePane returns pane addresses" \
  otmux.parameter.completion.sourcePane

PANE_OUT=$(otmux.parameter.completion.sourcePane 2>/dev/null)
PANE_COUNT=$(echo "$PANE_OUT" | grep -c ':' || true)

if [ "$PANE_COUNT" -gt 0 ]; then
  create.result 0 "panes"
else
  create.result 1 "empty"
fi
expect 0 "panes" "sourcePane completion should return pane addresses"

# ============================================================================
# T18: parameter.completion.session returns session names
# ============================================================================
test.case $level "T18: parameter.completion.session returns session names" \
  otmux.parameter.completion.session

SESS_OUT=$(otmux.parameter.completion.session 2>/dev/null)
SESS_COUNT=$(echo "$SESS_OUT" | wc -l | tr -d ' ')

if [ "$SESS_COUNT" -gt 0 ] && [ -n "$SESS_OUT" ]; then
  create.result 0 "sessions"
else
  create.result 1 "empty"
fi
expect 0 "sessions" "session completion should return session names"

# ============================================================================
# T19: parameter.completion.direction returns U/D/L/R only
# ============================================================================
test.case $level "T19: parameter.completion.direction returns U/D/L/R" \
  otmux.parameter.completion.direction

DIR_OUT=$(otmux.parameter.completion.direction 2>/dev/null)
DIR_SORTED=$(echo "$DIR_OUT" | sort)
EXPECTED=$(printf "D\nL\nR\nU")

if [ "$DIR_SORTED" = "$EXPECTED" ]; then
  create.result 0 "UDLR"
else
  create.result 1 "$DIR_SORTED"
fi
expect 0 "UDLR" "direction completion should return exactly U D L R"

# ============================================================================
# T20: parameter.completion.layout returns 5 layout names
# ============================================================================
test.case $level "T20: parameter.completion.layout returns 5 layouts" \
  otmux.parameter.completion.layout

LAYOUT_OUT=$(otmux.parameter.completion.layout 2>/dev/null)
LAYOUT_COUNT=$(echo "$LAYOUT_OUT" | wc -l | tr -d ' ')
HAS_TILED=$(echo "$LAYOUT_OUT" | grep -c "tiled" || true)
HAS_EVEN_H=$(echo "$LAYOUT_OUT" | grep -c "even-horizontal" || true)

if [ "$LAYOUT_COUNT" -eq 5 ] && [ "$HAS_TILED" -eq 1 ] && [ "$HAS_EVEN_H" -eq 1 ]; then
  create.result 0 "5-layouts"
else
  create.result 1 "count=$LAYOUT_COUNT"
fi
expect 0 "5-layouts" "layout completion should return 5 layout names"

# ============================================================================
# T21: parameter.completion.window returns window addresses
# ============================================================================
test.case $level "T21: parameter.completion.window returns window addresses" \
  otmux.parameter.completion.window

WIN_OUT=$(otmux.parameter.completion.window 2>/dev/null)
WIN_COUNT=$(echo "$WIN_OUT" | grep -c ':' || true)

if [ "$WIN_COUNT" -gt 0 ]; then
  create.result 0 "windows"
else
  create.result 1 "empty"
fi
expect 0 "windows" "window completion should return window addresses"

# ============================================================================
# T22: pane.swap with no args returns error
# ============================================================================
test.case $level "T22: pane.swap with no args returns error" \
  otmux pane.swap

create.result $RETURN_VALUE "error"
expect 1 "error" "pane.swap with no args should return error code 1"

# ============================================================================
# T23: pane.swap function has sourcePane and targetPane params
# ============================================================================
test.case $level "T23: pane.swap signature has sourcePane and targetPane" \
  grep "^otmux.pane.swap()" "$OOSH_DIR/otmux"

SIG=$(grep "^otmux.pane.swap()" "$OOSH_DIR/otmux" 2>/dev/null)
HAS_SOURCE=$(echo "$SIG" | grep -c "sourcePane" || true)
HAS_TARGET=$(echo "$SIG" | grep -c "targetPane" || true)

if [ "$HAS_SOURCE" -eq 1 ] && [ "$HAS_TARGET" -eq 1 ]; then
  create.result 0 "both-params"
else
  create.result 1 "sig=$SIG"
fi
expect 0 "both-params" "pane.swap should have sourcePane and targetPane params"

# ============================================================================
# T24: pane.join param renamed to window
# ============================================================================
test.case $level "T24: pane.join uses window param (not target)" \
  grep "^otmux.pane.join()" "$OOSH_DIR/otmux"

JOIN_SIG=$(grep "^otmux.pane.join()" "$OOSH_DIR/otmux" 2>/dev/null)
HAS_WINDOW=$(echo "$JOIN_SIG" | grep -c "<window>" || true)

if [ "$HAS_WINDOW" -eq 1 ]; then
  create.result 0 "window"
else
  create.result 1 "sig=$JOIN_SIG"
fi
expect 0 "window" "pane.join should use <window> param"

# ============================================================================
# T25: COMP_WORDBREAKS colon fix — c2.install removes colon (f38c12c)
# ============================================================================
test.case $level "T25: c2.install removes colon from COMP_WORDBREAKS" \
  grep "COMP_WORDBREAKS" "$OOSH_DIR/templates/user/c2.install"

CWFIX=$(grep 'COMP_WORDBREAKS=.*//.*:' "$OOSH_DIR/templates/user/c2.install" 2>/dev/null)
# Must be global (outside _oo_completion function), not local inside it
CWLOCAL=$(grep 'local COMP_WORDBREAKS' "$OOSH_DIR/templates/user/c2.install" 2>/dev/null)

if [ -n "$CWFIX" ] && [ -z "$CWLOCAL" ]; then
  create.result 0 "global"
else
  create.result 1 "missing-or-local"
fi
expect 0 "global" "COMP_WORDBREAKS colon removal must be global, not local"

# ============================================================================
# T26: parameter.completion.targetPane returns panes (2nd param works)
# ============================================================================
test.case $level "T26: parameter.completion.targetPane returns pane addresses" \
  otmux.parameter.completion.targetPane

TP_OUT=$(otmux.parameter.completion.targetPane 2>/dev/null)
TP_COUNT=$(echo "$TP_OUT" | grep -c ':' || true)

if [ "$TP_COUNT" -gt 0 ]; then
  create.result 0 "panes"
else
  create.result 1 "empty"
fi
expect 0 "panes" "targetPane completion should return pane addresses"

# ============================================================================
# T27: pane.move param renamed to window
# ============================================================================
test.case $level "T27: pane.move uses window param (not target)" \
  grep "^otmux.pane.move()" "$OOSH_DIR/otmux"

MOVE_SIG=$(grep "^otmux.pane.move()" "$OOSH_DIR/otmux" 2>/dev/null)
HAS_WINDOW=$(echo "$MOVE_SIG" | grep -c "<window>" || true)

if [ "$HAS_WINDOW" -eq 1 ]; then
  create.result 0 "window"
else
  create.result 1 "sig=$MOVE_SIG"
fi
expect 0 "window" "pane.move should use <window> param"

# ============================================================================
# T28: tree with session filter shows only that session
# ============================================================================
TEST_TREE_SESS="__test_tree_$$"
$TMUX_CMD new-session -d -s "$TEST_TREE_SESS" 2>/dev/null
TREE_FIXTURE_OK=$?

test.case $level "T28: tree with session filter shows only that session" \
  otmux tree "$TEST_TREE_SESS"

if [ "$TREE_FIXTURE_OK" -eq 0 ]; then
  TREE_FILTERED=$(otmux tree "$TEST_TREE_SESS" 2>/dev/null)
  HAS_TEST=$(echo "$TREE_FILTERED" | grep -c "$TEST_TREE_SESS" || true)
  TOTAL_HEADERS=$(echo "$TREE_FILTERED" | grep -cE "^[├└]── " || true)

  if [ "$HAS_TEST" -gt 0 ] && [ "$TOTAL_HEADERS" -le 1 ]; then
    create.result 0 "filtered"
  else
    create.result 1 "test=$HAS_TEST headers=$TOTAL_HEADERS"
  fi
else
  create.result 0 "skipped (tmux unavailable)"
fi
expect 0 "filtered" "tree with session arg should show only that session"

# ============================================================================
# T29: tree.detailed with session filter shows only that session
# ============================================================================
test.case $level "T29: tree.detailed with session filter shows only that session" \
  otmux tree.detailed "$TEST_TREE_SESS"

if [ "$TREE_FIXTURE_OK" -eq 0 ]; then
  DETAILED_FILTERED=$(otmux tree.detailed "$TEST_TREE_SESS" 2>/dev/null)
  HAS_TEST=$(echo "$DETAILED_FILTERED" | grep -c "$TEST_TREE_SESS" || true)
  TOTAL_HEADERS=$(echo "$DETAILED_FILTERED" | grep -cE "^[├└]── " || true)

  if [ "$HAS_TEST" -gt 0 ] && [ "$TOTAL_HEADERS" -le 1 ]; then
    create.result 0 "filtered"
  else
    create.result 1 "test=$HAS_TEST headers=$TOTAL_HEADERS"
  fi
else
  create.result 0 "skipped (tmux unavailable)"
fi
expect 0 "filtered" "tree.detailed with session arg should show only that session"

$TMUX_CMD kill-session -t "$TEST_TREE_SESS" 2>/dev/null

# ============================================================================
# T30: tree with no arg shows all sessions
# ============================================================================
test.case $level "T30: tree with no arg shows all sessions" \
  otmux tree

TREE_ALL=$(otmux tree 2>/dev/null)
ALL_COUNT=$(echo "$TREE_ALL" | grep -cE "^├──|^└──|│.*├──|│.*└──" || true)

if [ "$ALL_COUNT" -gt 3 ]; then
  create.result 0 "all"
else
  create.result 1 "count=$ALL_COUNT"
fi
expect 0 "all" "tree with no arg should show multiple sessions"

# ============================================================================
# T31: tree signature has <?session> optional param
# ============================================================================
test.case $level "T31: tree signature has optional session param" \
  grep "^otmux.tree()" "$OOSH_DIR/otmux"

TREE_SIG=$(grep "^otmux.tree()" "$OOSH_DIR/otmux" 2>/dev/null)
HAS_SESSION=$(echo "$TREE_SIG" | grep -c "<?session>" || true)

if [ "$HAS_SESSION" -eq 1 ]; then
  create.result 0 "optional"
else
  create.result 1 "sig=$TREE_SIG"
fi
expect 0 "optional" "tree should have <?session> optional param"

# ============================================================================
# T32: tree.detailed signature has <?session> optional param
# ============================================================================
test.case $level "T32: tree.detailed signature has optional session param" \
  grep "^otmux.tree.detailed()" "$OOSH_DIR/otmux"

TD_SIG=$(grep "^otmux.tree.detailed()" "$OOSH_DIR/otmux" 2>/dev/null)
HAS_SESSION=$(echo "$TD_SIG" | grep -c "<?session>" || true)

if [ "$HAS_SESSION" -eq 1 ]; then
  create.result 0 "optional"
else
  create.result 1 "sig=$TD_SIG"
fi
expect 0 "optional" "tree.detailed should have <?session> optional param"

# ============================================================================
# T33: send.key function defined in script
# ============================================================================
test.case $level "T33: otmux.send.key function defined" \
  grep "^otmux.send.key()" "$OOSH_DIR/otmux"

if grep -q "^otmux.send.key()" "$OOSH_DIR/otmux"; then
  create.result 0 "defined"
else
  create.result 1 "missing"
fi
expect 0 "defined" "otmux.send.key should be defined in otmux script"

# ============================================================================
# T34: send.key signature has target, key, optional count
# ============================================================================
test.case $level "T34: send.key has target key and optional count params" \
  grep "^otmux.send.key()" "$OOSH_DIR/otmux"

SK_SIG=$(grep "^otmux.send.key()" "$OOSH_DIR/otmux" 2>/dev/null)
HAS_TARGET=$(echo "$SK_SIG" | grep -c "<target>" || true)
HAS_KEY=$(echo "$SK_SIG" | grep -c "<key>" || true)
HAS_COUNT=$(echo "$SK_SIG" | grep -c "<?count" || true)

if [ "$HAS_TARGET" -eq 1 ] && [ "$HAS_KEY" -eq 1 ] && [ "$HAS_COUNT" -eq 1 ]; then
  create.result 0 "all-params"
else
  create.result 1 "sig=$SK_SIG"
fi
expect 0 "all-params" "send.key should have <target> <key> <?count:1>"

# ============================================================================
# T35: send.keys function defined in script
# ============================================================================
test.case $level "T35: otmux.send.keys function defined" \
  grep "^otmux.send.keys()" "$OOSH_DIR/otmux"

if grep -q "^otmux.send.keys()" "$OOSH_DIR/otmux"; then
  create.result 0 "defined"
else
  create.result 1 "missing"
fi
expect 0 "defined" "otmux.send.keys should be defined in otmux script"

# ============================================================================
# T36: send.key with no args returns error
# ============================================================================
test.case $level "T36: send.key with no args returns error" \
  otmux send.key

create.result $RETURN_VALUE "error"
expect 1 "error" "send.key with no args should return error code 1"

# ============================================================================
# T37: mid-line completion — c2.install handles midline detection
# ============================================================================
test.case $level "T37: c2.install has midline detection code" \
  grep "midline\|COMP_POINT" "$OOSH_DIR/templates/user/c2.install"

HAS_MIDLINE=$(grep -c "midline\|COMP_POINT" "$OOSH_DIR/templates/user/c2.install" 2>/dev/null || true)

if [ "$HAS_MIDLINE" -gt 0 ]; then
  create.result 0 "midline"
else
  create.result 1 "missing"
fi
expect 0 "midline" "2c.intsall should have midline/COMP_POINT detection for mid-line completion"

# ============================================================================
# T38: pane.history function exists
# ============================================================================
test.otmux.paneHistoryExists() {
  if type otmux.pane.history &>/dev/null; then
    create.result 0 "defined"
  else
    create.result 1 "missing"
  fi
}
test.case $level "T38: pane.history function exists" \
  test.otmux.paneHistoryExists
expect 0 "defined" "otmux.pane.history should be a defined function"

# ============================================================================
# T39: pane.history captures content from fixture session
# ============================================================================
TEST_SESS="__test_otmux_$$"

# Create a detached fixture session
$TMUX_CMD new-session -d -s "$TEST_SESS" 2>/dev/null
FIXTURE_OK=$?

test.case $level "T39: pane.history captures content from fixture session" \
  echo "fixture session created"

if [ "$FIXTURE_OK" -eq 0 ]; then
  # Send some recognisable text into the fixture pane
  $TMUX_CMD send-keys -t "$TEST_SESS" "echo OOSH_HISTORY_MARKER_$$" Enter
  sleep 0.3

  HIST_OUT=$(otmux.pane.history "$TEST_SESS" 50 2>/dev/null)

  if echo "$HIST_OUT" | grep -q "OOSH_HISTORY_MARKER_$$"; then
    create.result 0 "captured"
  else
    create.result 1 "marker not found in: $HIST_OUT"
  fi
else
  create.result 1 "fixture session creation failed"
fi
expect 0 "captured" "pane.history should capture content from fixture session"

# Cleanup T39 fixture
$TMUX_CMD kill-session -t "$TEST_SESS" 2>/dev/null

# ============================================================================
# T40: pane.history rejects missing target
# ============================================================================
test.case $level "T40: pane.history rejects missing target" \
  otmux pane.history

create.result $RETURN_VALUE "error"
expect 1 "error" "pane.history with no target should return error code 1"

# ============================================================================
# T41: pane.history respects line count param
# ============================================================================
TEST_SESS="__test_otmux_$$"
$TMUX_CMD new-session -d -s "$TEST_SESS" 2>/dev/null
FIXTURE_OK=$?

test.case $level "T41: pane.history respects line count param" \
  echo "line count test"

if [ "$FIXTURE_OK" -eq 0 ]; then
  # Send several lines so there is content to capture
  for i in 1 2 3 4 5 6 7 8 9 10; do
    $TMUX_CMD send-keys -t "$TEST_SESS" "echo LINE_$i" Enter
  done
  sleep 0.3

  # Capture only 3 lines — should return fewer lines than the full 10
  SHORT_HIST=$(otmux.pane.history "$TEST_SESS" 3 2>/dev/null)
  FULL_HIST=$(otmux.pane.history "$TEST_SESS" 100 2>/dev/null)

  SHORT_COUNT=$(echo "$SHORT_HIST" | grep -c "LINE_" || true)
  FULL_COUNT=$(echo "$FULL_HIST" | grep -c "LINE_" || true)

  if [ "$FULL_COUNT" -gt "$SHORT_COUNT" ] && [ "$SHORT_COUNT" -ge 0 ]; then
    create.result 0 "limited"
  else
    create.result 1 "short=$SHORT_COUNT full=$FULL_COUNT"
  fi
else
  create.result 1 "fixture session creation failed"
fi
expect 0 "limited" "pane.history with small line count should return fewer lines than full capture"

$TMUX_CMD kill-session -t "$TEST_SESS" 2>/dev/null

# ============================================================================
# T42: send.key functional — sends keypress to pane
# ============================================================================
TEST_SESS="__test_otmux_$$"
$TMUX_CMD new-session -d -s "$TEST_SESS" 2>/dev/null
FIXTURE_OK=$?

test.case $level "T42: send.key sends keypress to pane" \
  echo "send.key functional test"

if [ "$FIXTURE_OK" -eq 0 ]; then
  # Type text into the pane (without pressing Enter)
  $TMUX_CMD send-keys -t "$TEST_SESS" "ABCD"
  sleep 0.1

  # Use send.key to send BSpace (delete last char)
  otmux.send.key "$TEST_SESS" BSpace
  sleep 0.1

  # Now press Enter so the text appears in output
  $TMUX_CMD send-keys -t "$TEST_SESS" Enter
  sleep 0.2

  PANE_OUT=$(otmux.pane.history "$TEST_SESS" 10 2>/dev/null)

  # Should see "ABC" (D was deleted) but NOT "ABCD" as a command
  if echo "$PANE_OUT" | grep -q "ABC"; then
    create.result 0 "key-sent"
  else
    create.result 1 "output: $PANE_OUT"
  fi
else
  create.result 1 "fixture session creation failed"
fi
expect 0 "key-sent" "send.key BSpace should delete last character"

$TMUX_CMD kill-session -t "$TEST_SESS" 2>/dev/null

# ============================================================================
# T43: send.key with count param sends multiple
# ============================================================================
TEST_SESS="__test_otmux_$$"
$TMUX_CMD new-session -d -s "$TEST_SESS" 2>/dev/null
FIXTURE_OK=$?

test.case $level "T43: send.key with count param sends multiple" \
  echo "send.key count test"

if [ "$FIXTURE_OK" -eq 0 ]; then
  # Type text into the pane
  $TMUX_CMD send-keys -t "$TEST_SESS" "XYZWV"
  sleep 0.1

  # Delete 3 characters with count=3
  otmux.send.key "$TEST_SESS" BSpace 3
  sleep 0.1

  # Press Enter to execute
  $TMUX_CMD send-keys -t "$TEST_SESS" Enter
  sleep 0.2

  PANE_OUT=$(otmux.pane.history "$TEST_SESS" 10 2>/dev/null)

  # Should see "XY" (ZWV deleted by 3 BSpaces)
  if echo "$PANE_OUT" | grep -q "XY"; then
    create.result 0 "count-applied"
  else
    create.result 1 "output: $PANE_OUT"
  fi
else
  create.result 1 "fixture session creation failed"
fi
expect 0 "count-applied" "send.key with count=3 should delete 3 characters"

$TMUX_CMD kill-session -t "$TEST_SESS" 2>/dev/null

# ============================================================================
# T44: send.keys sends text to pane
# ============================================================================
TEST_SESS="__test_otmux_$$"
$TMUX_CMD new-session -d -s "$TEST_SESS" 2>/dev/null
FIXTURE_OK=$?

test.case $level "T44: send.keys sends text to pane" \
  echo "send.keys test"

if [ "$FIXTURE_OK" -eq 0 ]; then
  # Use send.keys to send text + Enter
  otmux.send.keys "$TEST_SESS" "echo SENDKEYS_MARKER_$$" Enter
  sleep 0.3

  PANE_OUT=$(otmux.pane.history "$TEST_SESS" 20 2>/dev/null)

  if echo "$PANE_OUT" | grep -q "SENDKEYS_MARKER_$$"; then
    create.result 0 "sent"
  else
    create.result 1 "marker not found in: $PANE_OUT"
  fi
else
  create.result 1 "fixture session creation failed"
fi
expect 0 "sent" "send.keys should deliver text to the target pane"

$TMUX_CMD kill-session -t "$TEST_SESS" 2>/dev/null

# ============================================================================
# T45: pane.swap swaps two panes
# ============================================================================
TEST_SESS="__test_otmux_$$"
$TMUX_CMD new-session -d -s "$TEST_SESS" 2>/dev/null
FIXTURE_OK=$?

test.case $level "T45: pane.swap swaps two panes" \
  echo "pane.swap test"

if [ "$FIXTURE_OK" -eq 0 ]; then
  # Detect actual first window and pane indices (respects base-index config)
  SWAP_WIN=$($TMUX_CMD list-windows -t "$TEST_SESS" -F "#{window_index}" 2>/dev/null | head -1)

  # Create a second pane by splitting
  $TMUX_CMD split-window -v -t "${TEST_SESS}:${SWAP_WIN}"
  sleep 0.1

  # Get both pane indices
  SWAP_P0=$($TMUX_CMD list-panes -t "${TEST_SESS}:${SWAP_WIN}" -F "#{pane_index}" 2>/dev/null | head -1)
  SWAP_P1=$($TMUX_CMD list-panes -t "${TEST_SESS}:${SWAP_WIN}" -F "#{pane_index}" 2>/dev/null | tail -1)

  # Record PIDs before swap — PIDs follow the pane process, not the position
  PID_P0_BEFORE=$($TMUX_CMD display-message -t "${TEST_SESS}:${SWAP_WIN}.${SWAP_P0}" -p "#{pane_pid}" 2>/dev/null)
  PID_P1_BEFORE=$($TMUX_CMD display-message -t "${TEST_SESS}:${SWAP_WIN}.${SWAP_P1}" -p "#{pane_pid}" 2>/dev/null)

  # Swap panes
  $TMUX_CMD swap-pane -s "${TEST_SESS}:${SWAP_WIN}.${SWAP_P0}" -t "${TEST_SESS}:${SWAP_WIN}.${SWAP_P1}"
  sleep 0.1

  # Check PIDs after swap — positions should have exchanged processes
  PID_P0_AFTER=$($TMUX_CMD display-message -t "${TEST_SESS}:${SWAP_WIN}.${SWAP_P0}" -p "#{pane_pid}" 2>/dev/null)
  PID_P1_AFTER=$($TMUX_CMD display-message -t "${TEST_SESS}:${SWAP_WIN}.${SWAP_P1}" -p "#{pane_pid}" 2>/dev/null)

  if [ "$PID_P0_AFTER" = "$PID_P1_BEFORE" ] && [ "$PID_P1_AFTER" = "$PID_P0_BEFORE" ]; then
    create.result 0 "swapped"
  else
    create.result 1 "before=[$PID_P0_BEFORE,$PID_P1_BEFORE] after=[$PID_P0_AFTER,$PID_P1_AFTER]"
  fi
else
  create.result 1 "fixture session creation failed"
fi
expect 0 "swapped" "pane.swap should exchange pane positions (titles follow panes)"

$TMUX_CMD kill-session -t "$TEST_SESS" 2>/dev/null

# ============================================================================
# Test Summary
# ============================================================================

test.suite.save.results
