#!/usr/bin/env bash
# orchestrate.sh — Fully automated orchestrator for session analysis
# Run in a SEPARATE terminal (not inside tmux).
# Prerequisites: tmux claude-grid session running with 6 panes, claude CLI installed.
set -euo pipefail

# ============================================================================
# CONFIG
# ============================================================================
REPO_ROOT="$HOME/work/all-things-quickcall/trace"
OUTPUT_DIR="$REPO_ROOT/docs/run1-09022026/analysis-outputs"
COORD_DIR="$OUTPUT_DIR/coordination"
PROMPT_DIR="$REPO_ROOT/scripts/analyze/prompts"
LOG_FILE="$COORD_DIR/orchestrator.log"
POLL_INTERVAL=15
STUCK_THRESHOLD=300  # 5 minutes without status update = stuck
TMUX_SESSION=""

# Agent definitions: name:pane_index:depends_on
# Pane indices match claude-grid.sh 6-pane layout
AGENTS=(
  "parser:0:none"
  "analyzer-a:1:parser"
  "analyzer-b:2:parser"
  "analyzer-c:3:parser"
  "synthesizer:4:analyzer-a,analyzer-b,analyzer-c"
  "renderer:5:synthesizer"
)

# Track which agents have been prompted (avoid re-sending)
declare -A PROMPTED

# ============================================================================
# HELPERS
# ============================================================================
log()  { echo "[$(date +%H:%M:%S)] $*" | tee -a "$LOG_FILE"; }
warn() { echo "[$(date +%H:%M:%S)] WARN: $*" | tee -a "$LOG_FILE"; }
err()  { echo "[$(date +%H:%M:%S)] ERROR: $*" | tee -a "$LOG_FILE" >&2; }

# Send a short text command to a tmux pane and press Enter
send_to_pane() {
  local pane="$1"; shift
  tmux send-keys -t "${TMUX_SESSION}:0.${pane}" "$*" Enter
}

# Read a field from an agent's coordination JSON
read_field() {
  local agent="$1" field="$2"
  local f="$COORD_DIR/${agent}.json"
  if [[ -f "$f" ]]; then
    python3 -c "import json; d=json.load(open('$f')); print(d.get('$field',''))" 2>/dev/null || echo ""
  else
    echo ""
  fi
}

# Read agent status (returns: not_started, in_progress, completed, failed)
read_status() {
  local s
  s=$(read_field "$1" "status")
  [[ -n "$s" ]] && echo "$s" || echo "not_started"
}

# Check if all listed dependencies have status "completed"
deps_met() {
  local deps="$1"
  [[ "$deps" == "none" ]] && return 0
  IFS=',' read -ra dep_list <<< "$deps"
  for dep in "${dep_list[@]}"; do
    [[ "$(read_status "$dep")" == "completed" ]] || return 1
  done
  return 0
}

# Check if a pane shows Claude waiting for input
# Claude Code shows a ">" or "?" prompt at the bottom when idle
pane_is_idle() {
  local pane="$1"
  local content
  content=$(tmux capture-pane -t "${TMUX_SESSION}:0.${pane}" -p 2>/dev/null | tail -5)
  # Match Claude's idle prompt patterns
  echo "$content" | grep -qE '(^>|How can I help|What would you)' && return 0
  return 1
}

# Check if agent's status file is stale (no update in STUCK_THRESHOLD seconds)
is_stale() {
  local agent="$1"
  local f="$COORD_DIR/${agent}.json"
  [[ ! -f "$f" ]] && return 1
  local status
  status=$(read_status "$agent")
  [[ "$status" != "in_progress" ]] && return 1
  python3 -c "
import os, time
mtime = os.path.getmtime('$f')
print('stale' if time.time() - mtime > $STUCK_THRESHOLD else 'ok')
" 2>/dev/null | grep -q "stale"
}

# Send the agent's prompt: tells Claude to read the prompt file
send_agent_prompt() {
  local name="$1" pane="$2"
  local prompt_file="$PROMPT_DIR/${name}.md"

  if [[ ! -f "$prompt_file" ]]; then
    err "Prompt file not found: $prompt_file"
    return 1
  fi

  log "Sending prompt to $name (pane $pane)"
  # Tell Claude to read the prompt file — avoids tmux escaping issues with large text
  send_to_pane "$pane" "Read the file $prompt_file and follow every instruction in it exactly. Start immediately. Do not ask questions — just execute."
  PROMPTED[$name]=1
}

# Git commit + push all analysis outputs
git_checkpoint() {
  local msg="$1"
  log "Git checkpoint: $msg"
  cd "$REPO_ROOT"
  git add docs/run1-09022026/analysis-outputs/ scripts/analyze/ 2>/dev/null || true
  git diff --cached --quiet 2>/dev/null && { log "Nothing to commit"; return 0; }
  git commit -m "analysis: $msg" --no-verify 2>/dev/null || true
  git push 2>/dev/null || warn "Push failed (will retry next checkpoint)"
  cd - >/dev/null
}

# ============================================================================
# AUTO-DETECT TMUX SESSION
# ============================================================================
detect_session() {
  TMUX_SESSION=$(tmux list-sessions -F '#{session_name}' 2>/dev/null | grep "claude-grid" | head -1)
  if [[ -z "$TMUX_SESSION" ]]; then
    err "No claude-grid tmux session found. Launch with:"
    err "  bash scripts/analyze/claude-grid.sh --yolo 6"
    exit 1
  fi
  log "Detected tmux session: $TMUX_SESSION"

  # Verify 6 panes exist
  local pane_count
  pane_count=$(tmux list-panes -t "${TMUX_SESSION}:0" 2>/dev/null | wc -l | tr -d ' ')
  if [[ "$pane_count" -lt 6 ]]; then
    err "Expected 6 panes, found $pane_count"
    exit 1
  fi
  log "Verified $pane_count panes"
}

# ============================================================================
# SETUP
# ============================================================================
setup() {
  mkdir -p "$COORD_DIR"

  # Create branch if not already on it
  cd "$REPO_ROOT"
  local current_branch
  current_branch=$(git branch --show-current)
  if [[ "$current_branch" != "analysis/run1-session-deep-dive" ]]; then
    log "Creating branch analysis/run1-session-deep-dive"
    git checkout -b "analysis/run1-session-deep-dive" 2>/dev/null || git checkout "analysis/run1-session-deep-dive"
  fi
  cd - >/dev/null

  # Write initial orchestrator status
  python3 -c "
import json, datetime
json.dump({
    'status': 'running',
    'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat(),
    'agents': {a.split(':')[0]: 'pending' for a in '''$(printf '%s\n' "${AGENTS[@]}")'''.strip().split('\n')}
}, open('$COORD_DIR/orchestrator.json', 'w'), indent=2)
"
}

# ============================================================================
# MAIN POLL LOOP
# ============================================================================
poll_loop() {
  log "========== POLL LOOP (every ${POLL_INTERVAL}s) =========="
  local cycle=0
  local last_checkpoint_cycle=0

  while true; do
    sleep "$POLL_INTERVAL"
    cycle=$((cycle + 1))
    local all_done=true
    local status_line=""
    local any_phase_completed=false

    for agent_def in "${AGENTS[@]}"; do
      IFS=':' read -r name pane deps <<< "$agent_def"
      local status
      status=$(read_status "$name")

      case "$status" in
        completed)
          status_line+="  $name=DONE"
          ;;
        in_progress)
          all_done=false
          local task
          task=$(read_field "$name" "current_task")
          local completed_count
          completed_count=$(python3 -c "import json; print(len(json.load(open('$COORD_DIR/${name}.json')).get('completed_tasks',[])))" 2>/dev/null || echo "?")
          status_line+="  $name=$task($completed_count)"

          # Check if stuck
          if is_stale "$name"; then
            warn "Agent $name stuck (no update in ${STUCK_THRESHOLD}s)"
            if pane_is_idle "$pane"; then
              log "Nudging stuck agent $name"
              send_to_pane "$pane" "You appear stuck. Check your progress, update $COORD_DIR/${name}.json with your current_task, and continue working. If you hit an error, set status to failed with error details."
            fi
          fi
          ;;
        failed|error)
          all_done=false
          local error_msg
          error_msg=$(read_field "$name" "error")
          status_line+="  $name=FAILED($error_msg)"

          # Auto-nudge: retry after failure
          if pane_is_idle "$pane"; then
            log "Auto-retrying failed agent $name"
            send_to_pane "$pane" "Your previous attempt failed. Read the error details in $COORD_DIR/${name}.json. Fix the issue and retry. Update status to in_progress when you resume."
          fi
          ;;
        not_started|"")
          all_done=false
          # Check dependencies and launch if ready
          if deps_met "$deps" && [[ -z "${PROMPTED[$name]:-}" ]]; then
            if pane_is_idle "$pane"; then
              send_agent_prompt "$name" "$pane"
              any_phase_completed=true
            else
              status_line+="  $name=BOOT"
            fi
          else
            if [[ -n "${PROMPTED[$name]:-}" ]]; then
              status_line+="  $name=SENT"
            else
              status_line+="  $name=WAIT"
            fi
          fi
          ;;
      esac
    done

    log "Cycle $cycle:$status_line"

    # Git checkpoint every 10 cycles (~2.5 min) if there's new work
    if (( cycle - last_checkpoint_cycle >= 10 )); then
      git_checkpoint "checkpoint at cycle $cycle"
      last_checkpoint_cycle=$cycle
    fi

    # Check if all agents are done
    if [[ "$all_done" == "true" ]]; then
      break
    fi
  done
}

# ============================================================================
# SUMMARY
# ============================================================================
summary() {
  log "========== ALL AGENTS COMPLETE =========="

  # Final git checkpoint
  git_checkpoint "all agents completed"

  echo ""
  echo "  Session Analysis Complete"
  echo "  ========================"
  echo ""
  echo "  Outputs:"
  echo "    Retrospective:  $OUTPUT_DIR/retrospective.md"
  echo "    Dashboard:      $OUTPUT_DIR/dashboard.html"
  echo "    Synthesis:      $OUTPUT_DIR/synthesis.md"
  echo "    Deep dives:     $OUTPUT_DIR/deep_dive/"
  echo "    Metrics:        $OUTPUT_DIR/metrics.json"
  echo "    Verification:   $COORD_DIR/verifier.json"
  echo ""

  # Check verifier status
  if [[ -f "$COORD_DIR/verifier.json" ]]; then
    local v_status
    v_status=$(python3 -c "import json; print(json.load(open('$COORD_DIR/verifier.json')).get('status','unknown'))" 2>/dev/null)
    echo "  Verification: $v_status"
  fi

  echo ""
  echo "  Branch: analysis/run1-session-deep-dive"
  echo "  To open dashboard: open $OUTPUT_DIR/dashboard.html"
  echo ""

  # Update orchestrator status
  python3 -c "
import json, datetime
d = json.load(open('$COORD_DIR/orchestrator.json'))
d['status'] = 'completed'
d['completed_at'] = datetime.datetime.now(datetime.timezone.utc).isoformat()
json.dump(d, open('$COORD_DIR/orchestrator.json', 'w'), indent=2)
"
}

# ============================================================================
# MAIN
# ============================================================================
main() {
  echo ""
  echo "  Session Analysis Orchestrator"
  echo "  6 agents, fully automated"
  echo ""

  # Verify prerequisites
  command -v tmux >/dev/null || { err "tmux not found"; exit 1; }
  command -v claude >/dev/null || { err "claude CLI not found"; exit 1; }
  command -v python3 >/dev/null || { err "python3 not found"; exit 1; }

  # Verify prompt files
  for f in parser.md analyzer-a.md analyzer-b.md analyzer-c.md synthesizer.md renderer.md; do
    [[ -f "$PROMPT_DIR/$f" ]] || { err "Missing prompt: $PROMPT_DIR/$f"; exit 1; }
  done
  log "All prompt files found"

  detect_session
  setup
  poll_loop
  summary
}

main "$@"
