#!/usr/bin/env bash
# pi.sh — dispatch the pi agent (openai-codex provider) under WRAPPER-CONTRACT. Invoke by path.
# Exit: 0 = completion, 124 = timeout/killed, 2 = usage error, 75 = rate-limited, 3 = engine down OR agent
#   returned 0 with empty captured output (silent write failure / disk full — success requires evidence).
set -uo pipefail

WORKSPACE="" PROMPT="" TASK_SLUG="" MODEL="" SESSION_ID="" TIMEOUT=360
MODE="dispatch"
while [[ $# -gt 0 ]]; do
  case "$1" in
    --workspace) [[ $# -lt 2 ]] && { echo '{"ok":false,"detail":"--workspace requires a value"}' >&2; exit 2; }; WORKSPACE="${2:-}"; shift 2;;
    --trust) [[ $# -lt 2 ]] && { echo '{"ok":false,"detail":"--trust requires a value"}' >&2; exit 2; }; PROMPT="${2:-}"; shift 2;;
    --task-slug) [[ $# -lt 2 ]] && { echo '{"ok":false,"detail":"--task-slug requires a value"}' >&2; exit 2; }; TASK_SLUG="${2:-}"; shift 2;;
    --model) [[ $# -lt 2 ]] && { echo '{"ok":false,"detail":"--model requires a value"}' >&2; exit 2; }; MODEL="${2:-}"; shift 2;;
    --session-id) [[ $# -lt 2 ]] && { echo '{"ok":false,"detail":"--session-id requires a value"}' >&2; exit 2; }; SESSION_ID="${2:-}"; shift 2;;
    --timeout) [[ $# -lt 2 ]] && { echo '{"ok":false,"detail":"--timeout requires a value"}' >&2; exit 2; }; TIMEOUT="${2:-}"; shift 2;;
    --health) MODE="health"; shift;;
    --list-models) MODE="list-models"; shift;;
    *) shift;;
  esac
done

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
source "$SCRIPT_DIR/lib/finalize.sh"
source "$SCRIPT_DIR/lib/spend-cap.sh"
_PI_BIN="${_PI_BIN:-pi}"
PI_AUTH_HOME="${PI_AUTH_HOME:-$HOME/.pi}"
PI_AUTH_FILE="$PI_AUTH_HOME/agent/auth.json"

make_log_dir() {
  local dir="$HOME/Projects/mega-plan-harness/tmp/logs"
  if ! mkdir -p "$dir" 2>/dev/null || [[ ! -d "$dir" || ! -w "$dir" ]]; then
    dir="${TMPDIR:-/tmp}/mega-plan-harness-logs"
    mkdir -p "$dir" || return 1
  fi
  printf '%s\n' "$dir"
}

parse_model_effort() {
  python3 - "$1" <<'PY'
import re
import sys

value = sys.argv[1]
match = re.match(r"^(.*)-(high|medium|low|xhigh)$", value)
if not match:
    raise SystemExit(1)
print(match.group(1))
print(match.group(2))
PY
}

has_pi_auth() {
  [[ -f "$PI_AUTH_FILE" ]] || return 1
  PI_AUTH_FILE="$PI_AUTH_FILE" python3 - <<'PY'
import json
import os
import sys

path = os.environ["PI_AUTH_FILE"]
try:
    with open(path, "r", encoding="utf-8") as handle:
        payload = json.load(handle)
except Exception:
    sys.exit(1)

credential = payload.get("openai-codex")
if not isinstance(credential, dict):
    sys.exit(1)
required = ("access", "refresh", "accountId")
for key in required:
    value = credential.get(key)
    if not isinstance(value, str) or not value.strip():
        sys.exit(1)
sys.exit(0)
PY
}

stream_output() {
  if [[ -n "${HARNESS_TRANSCRIPT_PATH:-}" ]]; then
    tee -a "$LOG" "$RAW_OUTPUT_FILE" "$HARNESS_TRANSCRIPT_PATH"
  else
    tee -a "$LOG" "$RAW_OUTPUT_FILE"
  fi
}

emit_event_line() {
  local line="$1"
  if [[ -n "${HARNESS_TRANSCRIPT_PATH:-}" ]]; then
    printf '%s\n' "$line" | tee -a "$LOG" "$HARNESS_TRANSCRIPT_PATH"
  else
    printf '%s\n' "$line" | tee -a "$LOG"
  fi
}

case "$MODE" in
  health)
    version_out="$("$_PI_BIN" --version 2>/dev/null)" || { echo '{"ok":false,"detail":"pi --version failed"}' >&2; exit 3; }
    version_out="$(printf '%s' "$version_out" | tail -n 1 | tr -d '\r')"
    VERSION_OUT="$version_out" python3 - <<'PY'
import json
import os
print(json.dumps({"ok": True, "version": os.environ.get("VERSION_OUT", "")}, separators=(",", ":")))
PY
    exit 0
    ;;
  list-models)
    "$_PI_BIN" models --json
    exit $?
    ;;
esac

TASK_SLUG="${TASK_SLUG//[^a-zA-Z0-9_-]/}"
RUN_ID="$(date +%Y-%m-%d-%H-%M-%S)-$$"

[[ -n "$WORKSPACE" && -d "$WORKSPACE" ]] || { echo '{"ok":false,"detail":"--workspace missing or not a dir"}' >&2; exit 2; }
[[ -n "$PROMPT" ]] || { echo '{"ok":false,"detail":"--trust (prompt) required"}' >&2; exit 2; }
[[ -n "$TASK_SLUG" ]] || { echo '{"ok":false,"detail":"--task-slug required (log + retry hygiene)"}' >&2; exit 2; }
[[ -n "$MODEL" ]] || { echo '{"ok":false,"detail":"--model required (no silent default)"}' >&2; exit 2; }

spend_cap_refuse_if_capped zync2 'pi' "$SESSION_ID" '' "$MODEL"
command -v "$_PI_BIN" >/dev/null 2>&1 || { echo '{"ok":false,"detail":"pi binary missing"}' >&2; exit 3; }
has_pi_auth || { echo '{"ok":false,"detail":"pi auth precondition unmet for provider openai-codex"}' >&2; exit 3; }

readarray -t MODEL_PARTS < <(parse_model_effort "$MODEL") || { echo '{"ok":false,"detail":"--model must end with -high|-medium|-low|-xhigh"}' >&2; exit 2; }
MODEL_NAME="${MODEL_PARTS[0]:-}"
MODEL_EFFORT="${MODEL_PARTS[1]:-}"
[[ -n "$MODEL_NAME" && -n "$MODEL_EFFORT" ]] || { echo '{"ok":false,"detail":"--model parse failed"}' >&2; exit 2; }

LOG_DIR="$(make_log_dir)" || { echo '{"ok":false,"detail":"log dir create failed"}' >&2; exit 3; }
LOG="$LOG_DIR/$RUN_ID-$TASK_SLUG.log"
RAW_OUTPUT_FILE="$LOG_DIR/$RUN_ID-$TASK_SLUG.raw"
if [[ -n "${HARNESS_TRANSCRIPT_PATH:-}" ]]; then
  mkdir -p "$(dirname "$HARNESS_TRANSCRIPT_PATH")" || { echo '{"ok":false,"detail":"transcript dir create failed"}' >&2; exit 3; }
fi

PI_ARGS=(run --json --provider openai-codex --model "$MODEL_NAME" --reasoning-effort "$MODEL_EFFORT" --cwd "$WORKSPACE")
[[ -n "$SESSION_ID" ]] && PI_ARGS+=(--session-id "$SESSION_ID")
PI_ARGS+=("$PROMPT")

{
  echo "=== TOOL: pi (openai-codex ${MODEL_NAME}/${MODEL_EFFORT}) ==="
  echo "=== CMD: $(printf '%q ' "$_PI_BIN" "${PI_ARGS[@]}") ==="
  echo "=== workspace: $WORKSPACE  timeout: ${TIMEOUT}s  log: $LOG ==="
  [[ -n "$SESSION_ID" ]] && echo "=== session_id: $SESSION_ID ==="
} | tee "$LOG"

cd "$WORKSPACE" || { echo '{"ok":false,"detail":"cd workspace failed"}' >&2; exit 2; }
timeout -k 5 "$TIMEOUT" "$_PI_BIN" "${PI_ARGS[@]}" < /dev/null 2>&1 | stream_output
RC="${PIPESTATUS[0]}"
raw_output="$(cat "$RAW_OUTPUT_FILE")"

echo "=== pi.sh exit=$RC ===" | tee -a "$LOG"
finalize_terminal "$RC" 'pi' "$SESSION_ID" '' "$MODEL"
