#!/usr/bin/env python3
"""Fail when core/ exceeds the kernel line budget from docs/kernel_spec.md.

Counts non-blank, non-comment lines in core/*.py (tests excluded).

Limits:
  - total core/ lines <= 4,000
  - any single file <= 500

Usage:
    python scripts/check_kernel_budget.py

Exit codes:
    0 — OK
    1 — budget exceeded
    2 — script error
"""
from __future__ import annotations

import sys
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parents[1]
CORE_DIR = REPO_ROOT / "core"

TOTAL_LIMIT = 4_000
FILE_LIMIT = 500

# Pre-kernel legacy files: counted toward total budget but exempt from the
# per-file cap until Phase 3 shrinks or splits core/config.py.
LEGACY_FILE_LIMIT_EXEMPT: frozenset[str] = frozenset({
    "core/__init__.py",
    "core/config.py",
})


def _count_lines(path: Path) -> int:
    try:
        text = path.read_text(encoding="utf-8")
    except OSError as exc:
        print(f"ERROR: cannot read {path}: {exc}", file=sys.stderr)
        raise SystemExit(2) from exc
    count = 0
    for line in text.splitlines():
        stripped = line.strip()
        if not stripped or stripped.startswith("#"):
            continue
        count += 1
    return count


def main() -> int:
    if not CORE_DIR.is_dir():
        print(f"ERROR: missing core directory: {CORE_DIR}", file=sys.stderr)
        return 2

    per_file: list[tuple[str, int]] = []
    total = 0
    for path in sorted(CORE_DIR.rglob("*.py")):
        rel = str(path.relative_to(REPO_ROOT)).replace("\\", "/")
        n = _count_lines(path)
        per_file.append((rel, n))
        total += n

    print("Kernel line budget:")
    for rel, n in per_file:
        exempt = rel in LEGACY_FILE_LIMIT_EXEMPT
        if exempt and n > FILE_LIMIT:
            flag = " legacy (exempt from per-file cap)"
        elif n > FILE_LIMIT:
            flag = " OVER"
        else:
            flag = ""
        print(f"  {n:5d}  {rel}{flag}")
    print(f"  {'—' * 5}")
    print(f"  {total:5d}  total (limit {TOTAL_LIMIT})")

    file_over = [
        (rel, n)
        for rel, n in per_file
        if n > FILE_LIMIT and rel not in LEGACY_FILE_LIMIT_EXEMPT
    ]
    total_over = total > TOTAL_LIMIT

    if file_over or total_over:
        if file_over:
            print("\nERROR: file limit exceeded:", file=sys.stderr)
            for rel, n in file_over:
                print(f"  {rel}: {n} > {FILE_LIMIT}", file=sys.stderr)
        if total_over:
            print(f"\nERROR: total {total} > {TOTAL_LIMIT}", file=sys.stderr)
        return 1

    print("OK: within kernel line budget")
    return 0


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