#!/usr/bin/env bash
# test-cx-implement.sh — both-branch test for cx-implement.sh via the CXI_CODEX_BIN mock seam.
# No real codex call. Asserts: (1) success branch commits codex's writes + ok=true + files listed;
# (2) no-op branch (codex exits 0 but writes nothing) → ok=false; (3) hard-fail branch (rc!=0) → ok=false;
# (4) usage error → exit 2.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WRAP="$HERE/cx-implement.sh"
TMP="$(mktemp -d)"; trap 'rm -rf "$TMP"' EXIT
PASS=0; FAIL=0
ok(){ PASS=$((PASS+1)); echo "ok   - $1"; }
no(){ FAIL=$((FAIL+1)); echo "FAIL - $1: $2"; }

mkrepo(){ local d="$1"; rm -rf "$d"; mkdir -p "$d"; git -C "$d" init -q; git -C "$d" config user.email t@t.t; git -C "$d" config user.name t; echo seed > "$d/seed.txt"; git -C "$d" add -A; git -C "$d" commit -qm seed; }

# mock that WRITES a file then exits 0 (simulates codex writing but NOT committing)
MOCK_WRITE="$TMP/mock-write"; cat > "$MOCK_WRITE" <<'EOF'
#!/usr/bin/env bash
# parse -C DIR out of args
dir=""; prev=""
for a in "$@"; do [[ "$prev" == "-C" ]] && dir="$a"; prev="$a"; done
[[ -n "$dir" ]] && printf 'codex-impl-ok\n' > "$dir/generated.txt"
exit 0
EOF
chmod +x "$MOCK_WRITE"

# mock that writes NOTHING, exits 0 (no-op)
MOCK_NOOP="$TMP/mock-noop"; printf '#!/usr/bin/env bash\nexit 0\n' > "$MOCK_NOOP"; chmod +x "$MOCK_NOOP"

# mock that hard-fails (rc=1, non-transient)
MOCK_FAIL="$TMP/mock-fail"; printf '#!/usr/bin/env bash\necho "boom" >&2\nexit 1\n' > "$MOCK_FAIL"; chmod +x "$MOCK_FAIL"

PF="$TMP/prompt.txt"; echo "do the thing" > "$PF"

# --- branch 1: success ---
R1="$TMP/r1"; mkrepo "$R1"
OUT="$(CXI_CODEX_BIN="$MOCK_WRITE" bash "$WRAP" --worktree "$R1" --task-slug t1 --prompt-file "$PF" --effort high --timeout 30)"
echo "$OUT" | grep -q '"ok":true' && ok "success → ok:true" || no "success" "$OUT"
echo "$OUT" | grep -q '"generated.txt"' && ok "success lists generated file" || no "success files" "$OUT"
[[ "$(git -C "$R1" log --oneline | wc -l)" -ge 2 ]] && ok "success committed draft" || no "success commit" "$(git -C "$R1" log --oneline)"

# --- branch 2: no-op (codex ok but no changes) ---
R2="$TMP/r2"; mkrepo "$R2"
OUT="$(CXI_CODEX_BIN="$MOCK_NOOP" bash "$WRAP" --worktree "$R2" --task-slug t2 --prompt-file "$PF")"
echo "$OUT" | grep -q '"ok":false' && ok "no-op → ok:false" || no "no-op" "$OUT"

# --- branch 3: hard fail ---
R3="$TMP/r3"; mkrepo "$R3"
OUT="$(CXI_CODEX_BIN="$MOCK_FAIL" bash "$WRAP" --worktree "$R3" --task-slug t3 --prompt-file "$PF")"
echo "$OUT" | grep -q '"ok":false' && ok "hard-fail → ok:false" || no "hard-fail" "$OUT"

# --- branch 4: usage error (missing worktree) → exit 2 ---
CXI_CODEX_BIN="$MOCK_NOOP" bash "$WRAP" --task-slug t4 --prompt-file "$PF" >/dev/null 2>&1
[[ $? -eq 2 ]] && ok "usage error → exit 2" || no "usage exit code" "got $?"

echo "----"; echo "PASS=$PASS FAIL=$FAIL"
[[ $FAIL -eq 0 ]]
