#!/usr/bin/env python3
"""Pre-commit hook: keep notebook outputs clear and bootstrap cells in sync.

Activated once per machine via `git config core.hooksPath .githooks`
(see docs/notebooks/README.md for the full explanation). Fixes any affected
notebook in place and re-stages it, so the commit proceeds with the fix already
applied -- no interruption, no separate re-commit step.
"""

import subprocess
import sys
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parent.parent
NOTEBOOKS_DIR = REPO_ROOT / "docs" / "notebooks"


def staged_files(pattern: str) -> list[str]:
    result = subprocess.run(
        ["git", "diff", "--cached", "--name-only", "--diff-filter=ACMR", "--", pattern],
        cwd=REPO_ROOT,
        capture_output=True,
        text=True,
        check=True,
    )
    return [line for line in result.stdout.splitlines() if line]


def main() -> int:
    if not NOTEBOOKS_DIR.exists():
        return 0

    staged_notebooks = staged_files("docs/notebooks/*.ipynb")
    template_staged = bool(staged_files("docs/notebooks/_mvtb_nb_bootstrap.py"))

    # Output-clearing only ever touches notebooks actually staged for this commit.
    output_targets = staged_notebooks

    # Bootstrap-cell regeneration also has to cover every notebook when the
    # template itself changed -- otherwise the other notebooks go stale and CI
    # fails on files this commit never touched.
    if template_staged:
        bootstrap_targets = sorted(
            str(p.relative_to(REPO_ROOT)) for p in NOTEBOOKS_DIR.glob("*.ipynb")
        )
    else:
        bootstrap_targets = staged_notebooks

    if not output_targets and not bootstrap_targets:
        return 0

    changed_paths: set[str] = set()

    try:
        if output_targets:
            paths = [str(REPO_ROOT / t) for t in output_targets]
            subprocess.run(
                [sys.executable, str(NOTEBOOKS_DIR / "clear_outputs.py"), *paths],
                cwd=REPO_ROOT,
                check=True,
            )
            changed_paths.update(paths)

        if bootstrap_targets:
            paths = [str(REPO_ROOT / t) for t in bootstrap_targets]
            subprocess.run(
                [sys.executable, str(NOTEBOOKS_DIR / "sync_bootstrap.py"), *paths],
                cwd=REPO_ROOT,
                check=True,
            )
            changed_paths.update(paths)
    except subprocess.CalledProcessError:
        print("pre-commit hook: notebook cleanup failed unexpectedly", file=sys.stderr)
        return 1

    if changed_paths:
        subprocess.run(["git", "add", "--", *sorted(changed_paths)], cwd=REPO_ROOT, check=True)

    return 0


if __name__ == "__main__":
    sys.exit(main())
