#!/usr/bin/env bash
# Tests resolve.sh in a sandboxed HOME so it touches no real session state.
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
RESOLVE="${HERE}/resolve.sh"
pass=0; fail=0
ok()   { pass=$((pass+1)); echo "ok   - $*"; }
bad()  { fail=$((fail+1)); echo "FAIL - $*"; }

SANDBOX="$(mktemp -d)"
trap 'rm -rf "$SANDBOX"' EXIT
# emulate cwd /work/app -> slug -work-app
WORK="${SANDBOX}/work/app"; mkdir -p "$WORK"
# slug must match resolve.sh's rule applied to the REAL absolute $WORK path.
SLUG="$(printf '%s' "$WORK" | tr '/.' '--')"
PROJ="${SANDBOX}/.claude/projects/${SLUG}"; mkdir -p "$PROJ"

run() { ( cd "$WORK" && HOME="$SANDBOX" bash "$RESOLVE" "$@" ); }

# fixtures: two top-level transcripts + a nested subagent one that must be ignored
printf '{"x":"hello UNIQUEMARK world"}\n' > "${PROJ}/sess-A.jsonl"
printf '{"x":"unrelated content"}\n'      > "${PROJ}/sess-B.jsonl"
mkdir -p "${PROJ}/subdir"
printf '{"x":"UNIQUEMARK in subagent"}\n' > "${PROJ}/subdir/nested.jsonl"

# 1. unique marker -> exactly sess-A, nested ignored
out=$(run lookup "UNIQUEMARK") || true
echo "$out" | grep -q "SESSION=sess-A" && ok "unique marker resolves top-level session" || bad "unique marker: got [$out]"
echo "$out" | grep -q "AGENT=$" && ok "no agent stored yet -> empty AGENT" || bad "expected empty AGENT: [$out]"
echo "$out" | grep -q "LASTREAD=0" && ok "no cursor yet -> LASTREAD=0" || bad "expected LASTREAD=0: [$out]"
echo "$out" | grep -q "NOW=1" && ok "NOW = transcript line count" || bad "expected NOW=1: [$out]"

# 2. zero matches -> exit 3
set +e; run lookup "NOPE_NOT_PRESENT" >/dev/null 2>&1; rc=$?; set -e
[ "$rc" -eq 3 ] && ok "zero matches -> exit 3" || bad "zero matches rc=$rc (want 3)"

# 3. multiple matches -> newest mtime wins
printf '{"x":"SHARED early turn"}\n' > "${PROJ}/sess-A.jsonl"
printf '{"x":"SHARED early turn"}\n' > "${PROJ}/sess-B.jsonl"
touch -d '2020-01-01' "${PROJ}/sess-A.jsonl"
touch -d '2020-06-01' "${PROJ}/sess-B.jsonl"   # B newer
out=$(run lookup "SHARED") || true
echo "$out" | grep -q "SESSION=sess-B" && ok "multiple matches -> newest mtime (sess-B)" || bad "mtime tiebreak: [$out]"

# 4. save then lookup -> AGENT populated
run save "sess-B" "a-test-id-123" >/dev/null
out=$(run lookup "SHARED") || true
echo "$out" | grep -q "AGENT=a-test-id-123" && ok "save persists agentId, lookup returns it" || bad "save/lookup: [$out]"

# 4b. read cursor: mark then lookup reflects offset; grow file -> delta visible
run mark "sess-B" "1" >/dev/null
printf '{"x":"SHARED new turn"}\n' >> "${PROJECT_B:=${PROJ}/sess-B.jsonl}"  # B now 2 lines
out=$(run lookup "SHARED") || true
echo "$out" | grep -q "LASTREAD=1" && ok "mark sets read cursor" || bad "mark cursor: [$out]"
echo "$out" | grep -q "NOW=2" && ok "NOW tracks grown transcript (delta = lines 2..2)" || bad "NOW after growth: [$out]"

# 4c. mark non-numeric -> fail
set +e; run mark "sess-B" "abc" >/dev/null 2>&1; rc=$?; set -e
[ "$rc" -ne 0 ] && ok "mark non-numeric -> nonzero" || bad "mark non-numeric should fail"

# 4d. agent subcommand: reads stored id, empty when none
[ "$(run agent sess-B)" = "a-test-id-123" ] && ok "agent subcommand returns stored id" || bad "agent read: [$(run agent sess-B)]"
[ -z "$(run agent sess-NOPE)" ] && ok "agent subcommand empty when no record" || bad "agent empty: [$(run agent sess-NOPE)]"

# 5. save needs both args -> fail
set +e; run save "only-session" >/dev/null 2>&1; rc=$?; set -e
[ "$rc" -ne 0 ] && ok "save missing id -> nonzero" || bad "save missing id should fail"

# 6. lookup with no marker -> fail
set +e; run lookup >/dev/null 2>&1; rc=$?; set -e
[ "$rc" -ne 0 ] && ok "lookup with no marker -> nonzero" || bad "lookup no marker should fail"

echo "----"; echo "pass=$pass fail=$fail"
[ "$fail" -eq 0 ]
