"""Crate-independence audit (SPEC §16 / REQ-DOD-CRATE-INDEPENDENCE).

The checkpoint module must remain reusable outside Attractor — that's
the contract that lets future projects (or external users) drop it
into their own workflow engine. To preserve that, the package may
only import from `pygit2` and the standard library; it must NOT
import from `attractor.<other>` modules.

We enforce this at the source level: any `import attractor.<something>`
or `from attractor.<something> import ...` is illegal UNLESS the
`<something>` starts with `checkpoint` (the package importing
itself is fine).
"""

import ast
from pathlib import Path

import attractor.checkpoint as cp_pkg


def _attractor_imports(source: str) -> list[str]:
    """Return every `attractor.*` name imported from `source`."""
    tree = ast.parse(source)
    out: list[str] = []
    for node in ast.walk(tree):
        if isinstance(node, ast.Import):
            for name in node.names:
                if name.name.startswith("attractor"):
                    out.append(name.name)
        elif isinstance(node, ast.ImportFrom):
            if node.module is not None and node.module.startswith("attractor"):
                out.append(node.module)
    return out


# [unit->REQ-DOD-CRATE-INDEPENDENCE]
class TestNoUpstreamImports:
    """Checkpoint package imports only itself and `pygit2`+stdlib."""

    def test_no_attractor_sibling_imports(self) -> None:
        package_dir = Path(cp_pkg.__file__).parent
        offenders: list[tuple[str, str]] = []
        for py_file in package_dir.rglob("*.py"):
            text = py_file.read_text(encoding="utf-8")
            for module in _attractor_imports(text):
                # Self-imports inside `attractor.checkpoint` are fine.
                if module == "attractor.checkpoint" or module.startswith(
                    "attractor.checkpoint."
                ):
                    continue
                # Top-level `import attractor` is also fine — it only
                # touches __version__ etc., not any sibling module.
                if module == "attractor":
                    continue
                offenders.append((py_file.name, module))
        assert not offenders, (
            "attractor.checkpoint must not depend on sibling packages "
            "(SPEC §16). Offending imports:\n"
            + "\n".join(f"  {f}: imports {mod}" for f, mod in offenders)
        )
