#!/usr/bin/env python3
"""Report broad except handlers in the active Mugi tree (excludes legacy/)."""
from __future__ import annotations

import re
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[2]
SCAN_ROOTS = [
    ROOT / "mugi_backend.py",
    ROOT / "knowledge_http_routes.py",
    ROOT / "memory_http_routes.py",
    ROOT / "diagnostics.py",
    ROOT / "tool_policy.py",
    ROOT / "agent_loop_run.py",
    ROOT / "agent_loop_config.py",
    ROOT / "tools",
    ROOT / "utils",
]
SKIP_PARTS = {"legacy", "__pycache__", ".git"}

EXCEPT_RE = re.compile(
    r"^(\s*)except\s+(Exception\b[^:]*|):\s*$",
    re.MULTILINE,
)

# Line ranges inside execute_raw_agent for attribution (agent_loop_run.py).
_EXECUTE_RAW_AGENT_REGIONS: tuple[tuple[int, int, str], ...] = (
    (399, 823, "setup"),
    (824, 1500, "injection"),
    (1501, 2468, "streaming_tool_defs"),
    (2469, 4428, "main_loop"),
    (4429, 999_999, "tool_helpers"),
)


def iter_py_files() -> list[Path]:
    out: list[Path] = []
    for base in SCAN_ROOTS:
        if base.is_file():
            out.append(base)
        elif base.is_dir():
            for p in base.rglob("*.py"):
                if any(part in SKIP_PARTS for part in p.parts):
                    continue
                out.append(p)
    return sorted(set(out))


def enclosing_function(lines: list[str], line_idx: int) -> str:
    for i in range(line_idx, -1, -1):
        m = re.match(r"^\s*def\s+(\w+)\s*\(", lines[i])
        if m:
            return m.group(1)
    return "<module>"


def execute_raw_agent_region(line_no: int) -> str:
    for start, end, name in _EXECUTE_RAW_AGENT_REGIONS:
        if start <= line_no <= end:
            return name
    return ""


def body_kind(lines: list[str], start: int) -> str:
    i = start + 1
    while i < len(lines) and not lines[i].strip():
        i += 1
    if i >= len(lines):
        return "empty"
    stripped = lines[i].strip()
    if stripped == "pass":
        return "pass"
    if stripped.startswith("continue"):
        return "continue"
    if stripped.startswith("return"):
        return "return"
    return "other"


def triage(body: str, func: str) -> str:
    if body in ("pass", "continue"):
        if func.startswith("_") or "best_effort" in func or "swallow" in func:
            return "intentional-best-effort"
        return "needs-logging"
    if body == "return":
        return "needs-user-surface"
    return "bug"


def main() -> int:
    rows: list[tuple[str, int, str, str, str, str, str]] = []
    for path in iter_py_files():
        try:
            text = path.read_text(encoding="utf-8", errors="replace")
        except OSError:
            continue
        lines = text.splitlines()
        rel = path.relative_to(ROOT)
        is_agent_loop = rel.name == "agent_loop_run.py"
        for m in EXCEPT_RE.finditer(text):
            line_no = text[: m.start()].count("\n") + 1
            func = enclosing_function(lines, line_no - 1)
            region = execute_raw_agent_region(line_no) if is_agent_loop else ""
            if is_agent_loop and region and func not in ("execute_raw_agent", "<module>"):
                func = f"{func}@{region}"
            bk = body_kind(lines, line_no - 1)
            tag = triage(bk, func)
            rows.append(
                (
                    str(rel),
                    line_no,
                    func,
                    region,
                    m.group(0).strip(),
                    bk,
                    tag,
                )
            )

    print(f"# bare_except_report — {len(rows)} handlers\n")
    print("file\tline\tfunction\tregion\texcept\tbody\ttriage")
    for row in rows:
        print("\t".join(str(x) for x in row))

    for silent_file in ("agent_loop_run.py", "agent_worker.py", "subagent_runner.py"):
        silent_pass = sum(1 for r in rows if r[0] == silent_file and r[5] == "pass")
        if silent_pass:
            print(
                f"\n# {silent_file} silent pass handlers: {silent_pass}",
                file=sys.stderr,
            )

    needs = sum(1 for r in rows if r[6] in ("needs-logging", "needs-user-surface", "bug"))
    print(f"\n# summary: total={len(rows)} flagged={needs}", file=sys.stderr)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
