#!/usr/bin/env bash
# claude_daemon.sh — Watches INBOX_DIR for *.request files, runs claude -p, writes *.response.
#
# Intended to run as a persistent background process (or systemd user service) so that
# Codex and other tools running in restricted sandboxes can query Claude without needing
# direct access to the claude binary.
#
# Request protocol:
#   Write a plain-text prompt to INBOX_DIR/<id>.request
#   Poll for INBOX_DIR/<id>.response (response text) or INBOX_DIR/<id>.error (failure)
#
# Environment variables:
#   CLAUDE_DAEMON_INBOX   inbox directory  (default: attic/CLAUDE/daemon/inbox)
#   CLAUDE_DAEMON_LOG     log file path    (default: attic/CLAUDE/daemon/daemon.log)
#   CLAUDE_DAEMON_MODEL   claude model     (default: sonnet)
#   CLAUDE_BIN            claude binary    (default: /home/elphel/.local/bin/claude)
#
# Usage:
#   claude_daemon.sh               # run in foreground
#   claude_daemon.sh --background  # fork to background, write PID to daemon.pid
#   claude_daemon.sh --stop        # stop a backgrounded instance
#   claude_daemon.sh --status      # show status

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WORKSPACE_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
DAEMON_DIR="$WORKSPACE_ROOT/attic/CLAUDE/daemon"

INBOX_DIR="${CLAUDE_DAEMON_INBOX:-$DAEMON_DIR/inbox}"
ARCHIVE_DIR="$DAEMON_DIR/archive"
LOG_FILE="${CLAUDE_DAEMON_LOG:-$DAEMON_DIR/daemon.log}"
PID_FILE="$DAEMON_DIR/daemon.pid"
CLAUDE_BIN="${CLAUDE_BIN:-/home/elphel/.local/bin/claude}"
CLAUDE_MODEL="${CLAUDE_DAEMON_MODEL:-sonnet}"
POLL_INTERVAL=1   # seconds between inbox scans

mkdir -p "$INBOX_DIR" "$ARCHIVE_DIR" "$(dirname "$LOG_FILE")"

# ── Helpers ──────────────────────────────────────────────────────────────────

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"; }

handle_request() {
  local req_file="$1"
  local base="${req_file%.request}"
  local resp_file="${base}.response"
  local err_file="${base}.error"
  local name
  name="$(basename "$req_file")"
  log "→ $name"

  if cd "$WORKSPACE_ROOT" && "$CLAUDE_BIN" \
        -p "$(cat "$req_file")" \
        --no-session-persistence \
        --model "$CLAUDE_MODEL" \
        > "$resp_file" 2>"$err_file"; then
    local size
    size="$(wc -c < "$resp_file")"
    log "  ✓ ${name%.request}.response  ($size bytes)"
    [[ -s "$err_file" ]] || rm -f "$err_file"
  else
    log "  ✗ claude exited non-zero — see ${name%.request}.error"
    echo "DAEMON ERROR: claude exited non-zero. Stderr in $(basename "$err_file")" >> "$resp_file"
  fi

  mv "$req_file" "$ARCHIVE_DIR/"
}

run_loop() {
  log "Claude daemon started (pid $$). Inbox: $INBOX_DIR"
  log "Model: $CLAUDE_MODEL  |  Poll: ${POLL_INTERVAL}s"

  # Handle any leftover requests from a previous run
  for req in "$INBOX_DIR"/*.request; do
    [[ -f "$req" ]] && handle_request "$req"
  done

  while true; do
    for req in "$INBOX_DIR"/*.request; do
      [[ -f "$req" ]] && handle_request "$req"
    done
    sleep "$POLL_INTERVAL"
  done
}

# ── CLI ───────────────────────────────────────────────────────────────────────

case "${1:-}" in
  --background)
    if [[ -f "$PID_FILE" ]]; then
      OLD_PID="$(cat "$PID_FILE")"
      if kill -0 "$OLD_PID" 2>/dev/null; then
        echo "Daemon already running (pid $OLD_PID)."
        exit 0
      fi
    fi
    nohup bash "$0" >> "$LOG_FILE" 2>&1 &
    echo $! > "$PID_FILE"
    echo "Claude daemon started in background (pid $(cat "$PID_FILE"))."
    echo "Log: $LOG_FILE"
    ;;

  --stop)
    if [[ -f "$PID_FILE" ]]; then
      PID="$(cat "$PID_FILE")"
      if kill -0 "$PID" 2>/dev/null; then
        kill "$PID"
        rm -f "$PID_FILE"
        echo "Daemon stopped (pid $PID)."
      else
        echo "PID file exists but process $PID is not running."
        rm -f "$PID_FILE"
      fi
    else
      echo "No PID file found. Daemon may not be running."
    fi
    ;;

  --status)
    if [[ -f "$PID_FILE" ]]; then
      PID="$(cat "$PID_FILE")"
      if kill -0 "$PID" 2>/dev/null; then
        echo "Daemon running (pid $PID)."
        echo "Log: $LOG_FILE"
        echo "Inbox: $INBOX_DIR ($(ls "$INBOX_DIR"/*.request 2>/dev/null | wc -l) pending)"
      else
        echo "Daemon NOT running (stale PID file: $PID)."
      fi
    else
      echo "Daemon NOT running (no PID file)."
    fi
    ;;

  ""|--foreground)
    run_loop
    ;;

  *)
    echo "Usage: claude_daemon.sh [--background|--stop|--status|--foreground]" >&2
    exit 1
    ;;
esac
