#!/usr/bin/env bash
set -euo pipefail

PROJECT_ROOT="${PROJECT_ROOT:-$(pwd)}"
CODEX_BIN="${CODEX_BIN:-codex}"
CODEX_SANDBOX="${CODEX_SANDBOX:-workspace-write}"
CODEX_MODEL="${CODEX_MODEL:-}"
TIMEBOX_SECONDS="${TIMEBOX_SECONDS:-1650}"
SLEEP_SECONDS="${SLEEP_SECONDS:-0}"
ALLOW_RESUME_LAST_FALLBACK="${ALLOW_RESUME_LAST_FALLBACK:-0}"
PROMPT_FILE="${PROMPT_FILE:-$PROJECT_ROOT/prompts/cron_session_prompt.md}"
SESSION_ID_FILE="${SESSION_ID_FILE:-$PROJECT_ROOT/.agent/codex_session_id}"
LOCK_FILE="${LOCK_FILE:-$PROJECT_ROOT/.agent/codex_supervisor.lock}"
SUPERVISOR_EVENT_FILE="${SUPERVISOR_EVENT_FILE:-}"
SNAPSHOT_PROMPT_LINES="${SNAPSHOT_PROMPT_LINES:-120}"

cd "$PROJECT_ROOT"
mkdir -p .agent/logs .agent/snapshots .agent/events docs prompts scripts

RUN_ID="$(date -u +%Y%m%dT%H%M%SZ)"
RUN_LOG="$PROJECT_ROOT/.agent/logs/run_${RUN_ID}.log"
RUN_MARK="$PROJECT_ROOT/.agent/run_${RUN_ID}.mark"
touch "$RUN_MARK"

exec > >(tee -a "$RUN_LOG") 2>&1

exec 9>"$LOCK_FILE"
if ! flock -n 9; then
  echo "[skip] another supervisor run is active: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
  exit 0
fi

echo "===== Codex supervisor no-git start: $(date -u +%Y-%m-%dT%H:%M:%SZ) ====="
echo "PROJECT_ROOT=$PROJECT_ROOT"
echo "RUN_ID=$RUN_ID"
echo "RUN_LOG=$RUN_LOG"

if command -v git >/dev/null 2>&1 && git rev-parse --show-toplevel >/dev/null 2>&1; then
  echo "[git] repo root: $(git rev-parse --show-toplevel)"
  echo "[git] status before:"
  git status --short || true
else
  echo "[git] not available or not a repository; continuing in no-git mode"
fi

SNAP="$PROJECT_ROOT/.agent/snapshots/snapshot_${RUN_ID}.txt"
{
  echo "# Snapshot $RUN_ID"
  echo
  echo "## pwd"
  pwd
  echo
  echo "## tmux ls"
  tmux ls 2>/dev/null || true
  echo
  echo "## interesting processes"
  ps -eo pid,ppid,etime,cmd --sort=etime 2>/dev/null \
    | grep -E 'codex|tmux|paper|live|router|tranche|collector|fetch_|backtest|python' \
    | grep -v grep \
    | sed -E 's/([A-Za-z0-9_]*(KEY|TOKEN|SECRET|PASSWORD|PASS|RPC|API)[A-Za-z0-9_]*=)"?[^" ]+"?/\1REDACTED/g' || true
  echo
  echo "## recent docs/prompts/scripts/backtest changes"
  find docs prompts scripts dex_platform -maxdepth 4 -type f 2>/dev/null \
    \( -name '*.md' -o -name '*.py' -o -name '*.sh' -o -name '*.yaml' -o -name '*.yml' -o -name '*.toml' \) \
    -printf '%TY-%Tm-%Td %TH:%TM %p\n' 2>/dev/null | sort | tail -120 || true
  echo
  echo "## latest reports"
  find DEX_REPORTS -maxdepth 4 -type f 2>/dev/null \
    \( -name 'README.md' -o -name '*summary*.csv' -o -name '*status*.md' -o -name '*handoff*.md' \) \
    -printf '%TY-%Tm-%Td %TH:%TM %p\n' 2>/dev/null | sort | tail -80 || true
} > "$SNAP"
echo "[snapshot] $SNAP"

if [[ ! -f "$PROMPT_FILE" ]]; then
  echo "[error] prompt file missing: $PROMPT_FILE"
  exit 2
fi

TMP_PROMPT="$PROJECT_ROOT/.agent/prompt_${RUN_ID}.md"
{
  echo "# Runtime Context"
  echo
  echo "UTC: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
  echo "Project root: $PROJECT_ROOT"
  echo "Snapshot file: $SNAP"
  echo
  if [[ -n "$SUPERVISOR_EVENT_FILE" && -f "$SUPERVISOR_EVENT_FILE" ]]; then
    echo "## Supervisor Event"
    echo '```text'
    sed -n '1,160p' "$SUPERVISOR_EVENT_FILE"
    echo '```'
    echo
  fi
  echo "## Snapshot excerpt"
  echo '```text'
  sed -n "1,${SNAPSHOT_PROMPT_LINES}p" "$SNAP"
  echo '```'
  echo
  echo "# Standing Instructions"
  cat "$PROMPT_FILE"
} > "$TMP_PROMPT"

CODEX_HOME_EFFECTIVE="${AGENT_CODEX_HOME:-${CODEX_HOME:-$HOME/.codex}}"
export CODEX_HOME="$CODEX_HOME_EFFECTIVE"
mkdir -p "$CODEX_HOME/sessions" 2>/dev/null || true
echo "CODEX_HOME=$CODEX_HOME"

run_codex() {
  local mode="$1"
  shift
  local cmd=(timeout "$TIMEBOX_SECONDS" "$CODEX_BIN" exec --sandbox "$CODEX_SANDBOX" --skip-git-repo-check)
  if [[ -n "$CODEX_MODEL" ]]; then
    cmd+=(-m "$CODEX_MODEL")
  fi
  if [[ "$mode" == "resume" ]]; then
    cmd+=(resume)
  fi
  "${cmd[@]}" "$@"
}

capture_new_session_id() {
  local candidates_file="$PROJECT_ROOT/.agent/session_candidates_${RUN_ID}.txt"
  find "$CODEX_HOME/sessions" -type f -newer "$RUN_MARK" 2>/dev/null | sort > "$candidates_file" || true
  local count
  count="$(wc -l < "$candidates_file" | tr -d ' ')"
  if [[ "$count" == "0" ]]; then
    echo "[session] no new session file detected"
    return 1
  fi
  echo "[session] new session file candidates:"
  cat "$candidates_file"

  python3 - "$candidates_file" "$SESSION_ID_FILE" <<'PY'
import re, sys
from pathlib import Path
cand = Path(sys.argv[1]).read_text().splitlines()
out = Path(sys.argv[2])
uuids = []
for p in cand:
    for m in re.finditer(r'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}', p):
        uuids.append(m.group(0))
# preserve order, unique
seen=[]
for u in uuids:
    if u not in seen:
        seen.append(u)
if len(seen) == 1:
    out.parent.mkdir(parents=True, exist_ok=True)
    out.write_text(seen[0] + "\n")
    print(f"[session] captured {seen[0]} -> {out}")
    sys.exit(0)
print(f"[session] could not infer exactly one UUID; found {seen}")
sys.exit(1)
PY
}

set +e
if [[ -s "$SESSION_ID_FILE" ]]; then
  SESSION_ID="$(tr -d '[:space:]' < "$SESSION_ID_FILE")"
  echo "[codex] resuming explicit session: $SESSION_ID"
  run_codex resume "$SESSION_ID" "$(cat "$TMP_PROMPT")"
  CODEX_EXIT=$?
else
  if [[ "$ALLOW_RESUME_LAST_FALLBACK" == "1" ]]; then
    echo "[codex] no explicit session id; using resume --last fallback because ALLOW_RESUME_LAST_FALLBACK=1"
    run_codex resume --last "$(cat "$TMP_PROMPT")"
    CODEX_EXIT=$?
  else
    echo "[codex] no explicit session id; starting new worker session"
    run_codex new "$(cat "$TMP_PROMPT")"
    CODEX_EXIT=$?
    capture_new_session_id || true
  fi
fi
set -e

echo "[codex] exit code: $CODEX_EXIT"

if command -v git >/dev/null 2>&1 && git rev-parse --show-toplevel >/dev/null 2>&1; then
  echo "[git] status after:"
  git status --short || true
  echo "[git] diff stat after:"
  git diff --stat || true
else
  echo "[nogit] latest modified relevant files after run:"
  find docs prompts scripts dex_platform .agent -maxdepth 4 -type f 2>/dev/null \
    -newer "$RUN_MARK" \
    ! -path '.agent/logs/*' \
    -printf '%TY-%Tm-%Td %TH:%TM %p\n' 2>/dev/null | sort || true
fi

echo "===== Codex supervisor no-git exit=$CODEX_EXIT: $(date -u +%Y-%m-%dT%H:%M:%SZ) ====="

if [[ "$SLEEP_SECONDS" != "0" ]]; then
  echo "Sleeping ${SLEEP_SECONDS}s before next run."
  sleep "$SLEEP_SECONDS"
fi

exit "$CODEX_EXIT"
