#!/usr/bin/env bash
#
# fleet-logs.sh — quickly inspect a fleet factory job's logs (agent-queue).
#
# The factory (learning_ai_devops_tools/agent-queue) writes two artifacts per job
# under queue/logs/:
#   • <base>.log                 — sparse runner lifecycle (launch, PR open, verify, errors)
#   • <base>.devin-export.json   — the live Devin transcript (steps[]: source + message)
# where <base> looks like 20260602-003202__fleet-<jobId>.
#
# Usage:
#   scripts/fleet-logs.sh [command] [job]
#
# Commands:
#   status [job]     steps count + slot (building/review/...) + latest step   (default)
#   tail   [job]     follow the runner .log (-f)
#   steps  [job] [N] last N transcript steps (default 12)
#   watch  [job] [N] live-refresh the last N steps every few seconds
#   full   [job]     all agent messages through your pager ($PAGER/less)
#   path   [job]     print the resolved log file paths
#   ls               list known jobs (newest first) with slot + step count
#
# `job` is a full or PARTIAL job id (e.g. `3c0586ce`). Omit it to use the most
# recent job. Override the factory location with AQ=/path/to/agent-queue.
#
set -euo pipefail

# ── Locate the agent-queue checkout ───────────────────────────────────────────
resolve_aq() {
  if [[ -n "${AQ:-}" ]]; then printf '%s' "$AQ"; return; fi
  local here parent
  here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  parent="$(cd "$here/../.." 2>/dev/null && pwd || true)"   # …/<code root>
  for cand in \
    "$parent/learning_ai_devops_tools/agent-queue" \
    "$HOME/code/mygh/learning_ai_devops_tools/agent-queue" \
    "$HOME/code/learning_ai_devops_tools/agent-queue"; do
    [[ -d "$cand/queue/logs" ]] && { printf '%s' "$cand"; return; }
  done
  return 1
}

AQ_DIR="$(resolve_aq || true)"
if [[ -z "$AQ_DIR" || ! -d "$AQ_DIR/queue/logs" ]]; then
  echo "error: agent-queue logs dir not found. Set AQ=/path/to/agent-queue." >&2
  exit 1
fi
LOGDIR="$AQ_DIR/queue/logs"
QUEUE="$AQ_DIR/queue"

have_jq() { command -v jq >/dev/null 2>&1; }
need_jq() { have_jq || { echo "error: 'jq' is required for this command (brew install jq)." >&2; exit 1; }; }

# ── Resolve a job's export file by (optional) substring; default = newest ──────
resolve_export() {
  local pat="${1:-}" f
  if [[ -z "$pat" ]]; then
    f="$(ls -t "$LOGDIR"/*.devin-export.json 2>/dev/null | head -1 || true)"
  else
    f="$(ls -t "$LOGDIR"/*"$pat"*.devin-export.json 2>/dev/null | head -1 || true)"
  fi
  [[ -n "$f" ]] || { echo "error: no transcript matching '${pat:-<latest>}' in $LOGDIR" >&2; return 1; }
  printf '%s' "$f"
}

base_of()  { basename "$1" .devin-export.json; }            # 20260602-…__fleet-<jobId>
runner_log() { printf '%s/%s.log' "$LOGDIR" "$(base_of "$1")"; }

slot_of() {
  local base="$1" d
  for d in building review testing shipped failed inbox; do
    [[ -e "$QUEUE/$d/$base.md" ]] && { printf '%s' "$d"; return; }
  done
  printf 'unknown'
}

steps_count() { have_jq && jq '.steps|length' "$1" 2>/dev/null || echo '?'; }

print_steps() {
  local exp="$1" n="${2:-12}"
  need_jq
  jq -r --argjson n "$n" '.steps[-$n:][] | "[\(.source)] \(.message[0:300])"' "$exp" 2>/dev/null \
    || echo "(transcript mid-write — re-run)"
}

cmd="${1:-status}"; shift || true

case "$cmd" in
  ls)
    printf '%-40s %-10s %-7s %s\n' "JOB (base)" "SLOT" "STEPS" "FILE"
    ls -t "$LOGDIR"/*.devin-export.json 2>/dev/null | while read -r f; do
      b="$(base_of "$f")"
      printf '%-40s %-10s %-7s %s\n' "$b" "$(slot_of "$b")" "$(steps_count "$f")" "$f"
    done
    ;;
  path)
    exp="$(resolve_export "${1:-}")"
    echo "transcript: $exp"
    echo "runner log: $(runner_log "$exp")"
    ;;
  status)
    exp="$(resolve_export "${1:-}")"; base="$(base_of "$exp")"
    echo "job:        $base"
    echo "slot:       $(slot_of "$base")"
    echo "steps:      $(steps_count "$exp")"
    echo "transcript: $exp"
    echo "--- latest step ---"
    print_steps "$exp" 3
    ;;
  tail)
    exp="$(resolve_export "${1:-}")"; log="$(runner_log "$exp")"
    echo "==> tail -f $log  (Ctrl-C to stop)"
    tail -n +1 -f "$log"
    ;;
  steps)
    exp="$(resolve_export "${1:-}")"
    print_steps "$exp" "${2:-12}"
    ;;
  watch)
    exp="$(resolve_export "${1:-}")"; n="${2:-8}"
    echo "==> live last $n steps of $(base_of "$exp")  (Ctrl-C to stop)"
    while true; do
      clear 2>/dev/null || true
      printf '== %s | slot=%s | steps=%s | %s ==\n\n' \
        "$(base_of "$exp")" "$(slot_of "$(base_of "$exp")")" "$(steps_count "$exp")" "$(date +%T)"
      print_steps "$exp" "$n"
      sleep 3
    done
    ;;
  full)
    exp="$(resolve_export "${1:-}")"; need_jq
    jq -r '.steps[] | "== \(.source) ==\n\(.message)\n"' "$exp" | "${PAGER:-less}"
    ;;
  -h|--help|help)
    sed -n '2,33p' "$0" | sed 's/^# \{0,1\}//'
    ;;
  *)
    echo "unknown command '$cmd' (try: status|tail|steps|watch|full|path|ls; -h for help)" >&2
    exit 1
    ;;
esac
