#!/usr/bin/env bash
# Aggregate REC-72b OAuth migration regression gate.
#
# This is intentionally the final REC-72b gate. It runs the mandatory
# dispatch audit, aggregates the Phase 1-3 suites, confirms the REC-72
# prompt-authoring engine/fallback aggregate still passes, and then applies
# exact file-scoped OAuth dispatch checks. The known paid Stage-1.5
# _call_opus/run_opus_enrichment path is explicitly out of scope here.
set -euo pipefail

HERE="$(cd "$(dirname "$0")" && pwd)"
REPO="$(cd "$HERE/../../../.." && pwd)"
cd "$REPO"

export PYTHONPATH="${PYTHONPATH:+$PYTHONPATH:}."

echo "== REC-72b mandatory dispatch audit =="
python3 recoil/pipeline/tools/audit_dispatch.py --project tartarus --episode ep_001

echo "== REC-72b Phase 1-3 regression suites =="
python3 -m pytest -q \
  recoil/pipeline/_lib/tests/test_opus_oauth.py \
  recoil/pipeline/_lib/tests/test_author_pass.py \
  recoil/pipeline/orchestrator/tests/test_storyboard_opus.py

echo "== REC-72 prompt-authoring engine/fallback regression =="
bash recoil/pipeline/tools/tests/test_rec72_prompt_authoring.sh

echo "== REC-72b exact OAuth dispatch gates =="
python3 - <<'PY'
import ast
from pathlib import Path


def fail(message: str) -> None:
    raise SystemExit(message)


def has_import_anthropic(path: Path) -> bool:
    tree = ast.parse(path.read_text(), filename=str(path))
    for node in ast.walk(tree):
        if isinstance(node, ast.Import):
            if any(alias.name == "anthropic" for alias in node.names):
                return True
        elif isinstance(node, ast.ImportFrom) and node.module == "anthropic":
            return True
    return False


opus_oauth = Path("recoil/pipeline/_lib/opus_oauth.py")
dispatch_payload = Path("recoil/pipeline/_lib/dispatch_payload.py")

if has_import_anthropic(opus_oauth):
    fail(f"{opus_oauth} imports anthropic")
if has_import_anthropic(dispatch_payload):
    fail(f"{dispatch_payload} imports anthropic")

tree = ast.parse(opus_oauth.read_text(), filename=str(opus_oauth))
for parent in ast.walk(tree):
    for child in ast.iter_child_nodes(parent):
        child._rec72b_parent = parent

anthropic_key_lines = []
env_pop_lines = []
for node in ast.walk(tree):
    if isinstance(node, ast.Constant) and node.value == "ANTHROPIC_API_KEY":
        anthropic_key_lines.append(node.lineno)
        parent = getattr(node, "_rec72b_parent", None)
        if (
            isinstance(parent, ast.Call)
            and isinstance(parent.func, ast.Attribute)
            and parent.func.attr == "pop"
            and isinstance(parent.func.value, ast.Name)
            and parent.func.value.id == "env"
        ):
            env_pop_lines.append(node.lineno)

if anthropic_key_lines != env_pop_lines:
    fail(
        f"{opus_oauth} reads ANTHROPIC_API_KEY outside env.pop: "
        f"all={anthropic_key_lines}, env.pop={env_pop_lines}"
    )

print("exact OAuth static gates OK")
PY

# Exact storyboard grep: only assert the live storyboard pass calls
# call_opus_oauth. Explicitly exclude the known paid Stage-1.5
# _call_opus/run_opus_enrichment path; do not inspect it for anthropic usage.
echo "excluding known paid Stage-1.5 path: _call_opus/run_opus_enrichment"
awk '
  /^    def run_storyboard_pass\(/ {in_func=1}
  in_func {print}
  in_func && /^    def / && $0 !~ /^    def run_storyboard_pass\(/ {exit}
' recoil/pipeline/orchestrator/ingest_pipeline.py | grep -q 'call_opus_oauth'
echo "storyboard call_opus_oauth grep gate OK"

echo "REC-72b OAuth aggregate OK"
