#!/usr/bin/env bash
# A stand-in for `claude` in tests. Records every call (cwd and arguments) in $FAKE_CLAUDE_STATE/calls.jsonl,
# fakes `--bg` sessions with job state files, and serves `agents --json [--all]` from agents.json.
set -euo pipefail
S=${FAKE_CLAUDE_STATE:?set FAKE_CLAUDE_STATE}
mkdir -p "$S"
[ -f "$S/agents.json" ] || echo '[]' > "$S/agents.json"
{ [ $# -gt 0 ] && printf '%s\0' "$@"; } | jq -cRs --arg cwd "$PWD" '{cwd: $cwd, args: (split("\u0000") | .[:-1])}' >> "$S/calls.jsonl"
env > "$S/last.env"   # the environment of the latest call, for the session's own variables

set_agents() { local tmp; tmp=$(mktemp); jq "$@" "$S/agents.json" > "$tmp" && mv "$tmp" "$S/agents.json"; }

case "${1:-}" in
  --version) echo "0.0.0 (fake)" ;;
  # Without --all, only what Claude Code counts as active: a session with a process, or one still working
  # or blocked on a person without one (a schedule armed keeps a stopped session "working"). A finished
  # session whose process is gone drops out, as observed on 2.1.295.
  agents)
    [ "${FAKE_CLAUDE_AGENTS_FAIL:-}" = 1 ] && { echo "agents failed (fake)" >&2; exit 1; }
    if [ -n "${FAKE_CLAUDE_AGENTS_FAIL_AFTER:-}" ]; then # the first n reads work, later ones fail
      n=$(( $(cat "$S/agents-reads" 2>/dev/null || echo 0) + 1 )); echo "$n" > "$S/agents-reads"
      [ "$n" -le "$FAKE_CLAUDE_AGENTS_FAIL_AFTER" ] || { echo "agents failed (fake)" >&2; exit 1; }
    fi
    if printf '%s\n' "$@" | grep -qx -- --all; then cat "$S/agents.json"
    else jq 'map(select(has("pid") or ((.state // "") | IN("working", "blocked"))))' "$S/agents.json"; fi ;;
  # A session with a schedule armed stays listed as "working" once stopped (FAKE_CLAUDE_STOP_KEEPS_STATE).
  stop) sleep "${FAKE_CLAUDE_STOP_DELAY:-0}"
    if [ "${FAKE_CLAUDE_STOP_KEEPS_STATE:-}" = 1 ]; then set_agents --arg id "$2" 'map(if .id == $id then del(.pid, .status) else . end)'
    else set_agents --arg id "$2" 'map(if .id == $id then .state = "stopped" | del(.pid) else . end)'; fi ;;
  rm) set_agents --arg id "$2" 'map(select(.id != $id))' ;;
  # Print mode reads /context of a session and /usage without a model call; it prints what Claude Code
  # prints with --output-format stream-json --verbose, and keeps the settings it was given.
  -p)
    prev=""; for a in "$@"; do
      [ "$prev" = --settings ] && { if [ -f "$a" ]; then cat "$a"; else printf '%s' "$a"; fi > "$S/p-settings.json"; }
      prev=$a
    done
    echo '{"type":"system","subtype":"init"}'
    if printf '%s\n' "$@" | grep -qx /context; then
      echo '{"type":"assistant","context_usage":{"model":"claude-opus-5-5","total_tokens":95300,"raw_max_tokens":200000,"percentage":48,"categories":[{"name":"System prompt","tokens":3000,"kind":"used"},{"name":"Messages","tokens":57600,"kind":"used"},{"name":"Free space","tokens":106400,"kind":"free"},{"name":"Autocompact buffer","tokens":33000,"kind":"buffer"}],"mcp_tools":[{"name":"mcp__tares__a","server_name":"tares","tokens":120}],"skills":[{"name":"station-builder","source":"plugin","tokens":800}]}}'
    elif printf '%s\n' "$@" | grep -qx /usage && [ -z "${FAKE_CLAUDE_NO_PLAN:-}" ]; then
      echo '{"type":"assistant","usage_report":{"rate_limits":{"limits":[{"kind":"session","percent":27,"resets_at":"2099-01-01T17:00:00+00:00","scope":null,"is_active":true},{"kind":"weekly_all","percent":5,"resets_at":"2099-01-05T00:00:00+00:00","scope":null,"is_active":false}],"extra_usage":{"is_enabled":false}}}}'
    fi
    echo '{"type":"result","subtype":"success"}' ;;
  --bg)
    if [ "${FAKE_CLAUDE_FAIL_RESUME:-}" = 1 ] && printf '%s\n' "$@" | grep -qx -- --resume; then echo "resume failed (fake)"; exit 1; fi
    sleep "${FAKE_CLAUDE_BG_DELAY:-0}" # Claude Code takes a moment to register a new session
    name=""; prev=""
    for a in "$@"; do [ "$prev" = "-n" ] && name=$a; prev=$a; done
    n=$(( $(cat "$S/n" 2>/dev/null || echo 0) + 1 )); echo "$n" > "$S/n"
    id=$(printf '%08x' "$n")
    mkdir -p "$HOME/.claude/jobs/$id"
    jq -n --arg s "session-$n" '{sessionId: $s}' > "$HOME/.claude/jobs/$id/state.json"
    set_agents --arg id "$id" --arg n "$name" --arg cwd "$PWD" --arg s "session-$n" --argjson at "$n" \
      '. + [{id: $id, name: $n, cwd: $cwd, state: "working", sessionId: $s, startedAt: $at, pid: (40000 + $at)}]'
    printf 'backgrounded · %s · %s\n' "$id" "$name" ;;
esac
