#!/usr/bin/env bash

_FINALIZE_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
_FINALIZE_USAGE_PY="$_FINALIZE_LIB_DIR/usage-event.py"
_FINALIZE_STATUS_PY="$_FINALIZE_LIB_DIR/verdict-status.py"

finalize_terminal() {
  local dispatch_rc="$1" detail="$2" thread_id="$3" protocol="$4" model="$5" contract_rc resume_at status_json
  if [[ $dispatch_rc -eq 0 ]]; then contract_rc=0
  elif [[ $dispatch_rc -eq 124 || $dispatch_rc -eq 137 ]]; then contract_rc=124
  elif [[ $dispatch_rc -eq 2 ]]; then contract_rc=2
  elif LC_ALL=C grep -qiE 'usage limit|rate.?limit|too many requests|quota exhausted|subscription.*exhausted|(^|[^0-9])429([^0-9]|$)' "$RAW_OUTPUT_FILE" 2>/dev/null; then contract_rc=75
  else contract_rc=3; fi
  if [[ $contract_rc -eq 0 ]] && ! LC_ALL=C grep -q '[^[:space:]]' "$RAW_OUTPUT_FILE" 2>/dev/null; then contract_rc=3; fi
  if [[ $contract_rc -eq 75 ]]; then
    detail="rate-limited"
    resume_at="$(RAW_OUTPUT_FILE="$RAW_OUTPUT_FILE" python3 - <<'PY'
import datetime
import json
import os
import re

try:
    with open(os.environ["RAW_OUTPUT_FILE"], encoding="utf-8") as handle:
        raw = handle.read()
except OSError:
    raw = ""
now = datetime.datetime.now().astimezone()
resume = ""

def resume_from(value):
    if isinstance(value, dict):
        candidate = value.get("resume_at")
        if isinstance(candidate, str) and re.fullmatch(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})", candidate):
            return candidate
        for nested in value.values():
            found = resume_from(nested)
            if found:
                return found
    elif isinstance(value, list):
        for nested in value:
            found = resume_from(nested)
            if found:
                return found
    return ""

for document in (raw, *raw.splitlines()):
    try:
        resume = resume_from(json.loads(document))
    except json.JSONDecodeError:
        continue
    if resume:
        break

match = re.search(r"try again in\s+(?:(\d+)\s*hours?)?\s*(?:(\d+)\s*minutes?)?", raw, re.I)
if not resume and match and (match.group(1) or match.group(2)):
    delta = datetime.timedelta(hours=int(match.group(1) or 0), minutes=int(match.group(2) or 0))
    resume = (now + delta).isoformat()
elif not resume:
    match = re.search(r"try again at\s+(\d{1,2}):(\d{2})\s*(AM|PM)?", raw, re.I)
    if match:
        hour, minute = int(match.group(1)), int(match.group(2))
        ampm = (match.group(3) or "").upper()
        if ampm == "PM" and hour < 12:
            hour += 12
        if ampm == "AM" and hour == 12:
            hour = 0
        candidate = now.replace(hour=hour, minute=minute, second=0, microsecond=0)
        if candidate <= now:
            candidate += datetime.timedelta(days=1)
        resume = candidate.isoformat()
print(resume)
PY
)"
  elif [[ $contract_rc -ne 0 ]]; then
    detail="$detail failed"
  else
    detail="$detail completed"
  fi
  status_json="$(RAW_OUTPUT_FILE="$RAW_OUTPUT_FILE" OK="$([[ $contract_rc -eq 0 ]] && printf 1 || printf 0)" DETAIL="$detail" THREAD_ID="$thread_id" PROTOCOL="$protocol" python3 "$_FINALIZE_STATUS_PY")" || exit 3
  if [[ $contract_rc -eq 75 ]]; then
    status_json="$(STATUS_JSON="$status_json" RESUME_AT="$resume_at" python3 - <<'PY'
import json
import os

status = json.loads(os.environ["STATUS_JSON"])
status["resume_at"] = os.environ["RESUME_AT"]
print(json.dumps(status, separators=(",", ":")))
PY
)" || exit 3
  fi
  [[ -n "${status_json//[[:space:]]/}" ]] || exit 3
  emit_event_line "$(python3 "$_FINALIZE_USAGE_PY" "$RAW_OUTPUT_FILE" "$model")"
  emit_event_line "$status_json"
  exit "$contract_rc"
}
