#!/usr/bin/env bash
# dead-advisor session resolver + agent-id sidecar.
# Fail-closed: any unexpected state -> nonzero exit + stderr, never a wrong-session guess.
#
#   resolve.sh lookup <MARKER>        resolve THIS session's transcript via MARKER; print
#                                     TRANSCRIPT/SESSION/AGENT/LASTREAD/NOW. exit 3 = no match.
#   resolve.sh save <SESSION> <ID>    persist the spawned subagent's agentId for this session.
#   resolve.sh agent <SESSION>        print the stored agentId for this session (empty if none). Read-only.
#   resolve.sh mark <SESSION> <N>     record the transcript line count the subagent just read,
#                                     so the next call's delta range starts there (read cursor).
set -euo pipefail

STATE_DIR="${HOME}/.claude/dead-advisor-state"

die() { echo "dead-advisor: $*" >&2; exit 1; }

slug_of_cwd() {
  # cwd slug = PWD with every '/' and '.' -> '-' (matches ~/.claude/projects/<slug> layout)
  printf '%s' "$PWD" | tr '/.' '--'
}

cmd_lookup() {
  local marker="${1:-}"
  [ -n "$marker" ] || die "lookup needs a MARKER"
  local dir="${HOME}/.claude/projects/$(slug_of_cwd)"
  [ -d "$dir" ] || die "transcript dir not found: $dir"

  # top-level *.jsonl only; nested dirs are subagent transcripts.
  local files match
  files=$(find "$dir" -maxdepth 1 -name '*.jsonl' 2>/dev/null) || true
  [ -n "$files" ] || die "no transcripts under $dir"

  # files containing the literal MARKER; multiple (resumed/forked) -> newest mtime wins.
  match=$(grep -lF "$marker" $files </dev/null 2>/dev/null | xargs -r ls -t 2>/dev/null | head -1) || true
  [ -n "$match" ] || { echo "dead-advisor: MARKER matched no transcript; supply a more unique/earlier substring" >&2; exit 3; }

  local session agent_file agent_id="" read_file lastread=0 now
  session=$(basename "$match" .jsonl)
  agent_file="${STATE_DIR}/${session}.id"
  [ -f "$agent_file" ] && agent_id=$(head -1 "$agent_file" 2>/dev/null || true)
  read_file="${STATE_DIR}/${session}.read"
  [ -f "$read_file" ] && lastread=$(head -1 "$read_file" 2>/dev/null || echo 0)
  case "$lastread" in (*[!0-9]*|'') lastread=0 ;; esac
  now=$(wc -l < "$match" 2>/dev/null | tr -d ' '); [ -n "$now" ] || now=0

  echo "TRANSCRIPT=${match}"
  echo "SESSION=${session}"
  echo "AGENT=${agent_id}"
  echo "LASTREAD=${lastread}"
  echo "NOW=${now}"
}

cmd_agent() {
  local session="${1:-}"
  [ -n "$session" ] || die "agent needs SESSION"
  local f="${STATE_DIR}/${session}.id"
  [ -f "$f" ] && head -1 "$f" 2>/dev/null || true
}

cmd_mark() {
  local session="${1:-}" n="${2:-}"
  [ -n "$session" ] || die "mark needs SESSION"
  case "$n" in (''|*[!0-9]*) die "mark needs a numeric line count" ;; esac
  mkdir -p "$STATE_DIR"
  printf '%s\n' "$n" > "${STATE_DIR}/${session}.read"
  echo "marked ${session} read=${n}"
}

cmd_save() {
  local session="${1:-}" id="${2:-}"
  [ -n "$session" ] || die "save needs SESSION"
  [ -n "$id" ] || die "save needs AGENT_ID"
  mkdir -p "$STATE_DIR"
  printf '%s\n' "$id" > "${STATE_DIR}/${session}.id"
  echo "saved ${session} -> ${id}"
}

case "${1:-}" in
  lookup) shift; cmd_lookup "$@" ;;
  save)   shift; cmd_save "$@" ;;
  agent)  shift; cmd_agent "$@" ;;
  mark)   shift; cmd_mark "$@" ;;
  *)      die "usage: resolve.sh {lookup <MARKER>|save <SESSION> <ID>|agent <SESSION>|mark <SESSION> <N>}" ;;
esac
