#!/usr/bin/env python3
"""Build the single-file tikzphysics.sty used for direct Overleaf upload."""

from __future__ import annotations

import argparse
from pathlib import Path
import re
import sys


ROOT = Path(__file__).resolve().parents[1]
OUTPUT = ROOT / "output" / "overleaf" / "tikzphysics.sty"
MODULES = (
    "tikzlibrarytikzphysics.catalog.code.tex",
    "tikzlibrarytikzphysics.core.code.tex",
    "tikzlibrarytikzphysics.surface.code.tex",
    "tikzlibrarytikzphysics.ramps.code.tex",
    "tikzlibrarytikzphysics.mechanics.code.tex",
    "tikzlibrarytikzphysics.optics.code.tex",
)
SKIP_LINES = {
    r"\endinput",
    r"\usetikzlibrary{tikzphysics.catalog}",
    r"\usetikzlibrary{tikzphysics.core}",
}


def module_body(path: Path) -> str:
    lines = path.read_text(encoding="utf-8").splitlines()
    return "\n".join(line for line in lines if line.strip() not in SKIP_LINES)


def build_bundle() -> str:
    wrapper = (ROOT / "tikzphysics.sty").read_text(encoding="utf-8")
    match = re.search(r"^\\ProvidesPackage\{tikzphysics\}.*$", wrapper, re.MULTILINE)
    if match is None:
        raise RuntimeError("could not find the package identity in tikzphysics.sty")
    provides_package = match.group(0)
    sections = [
        """%% tikzphysics.sty -- generated single-file Overleaf bundle
%% Generated by scripts/build_overleaf_bundle.py; do not edit this copy.
%% Source modules remain the canonical CTAN/runtime implementation.
\\NeedsTeXFormat{LaTeX2e}
"""
    ]
    sections.append(f"{provides_package}\n\\RequirePackage{{tikz}}\n")
    for name in MODULES:
        sections.append(f"\n%% ===== BEGIN INLINED {name} =====\n")
        sections.append(module_body(ROOT / name))
        sections.append(f"\n%% ===== END INLINED {name} =====\n")
    sections.append("\n\\endinput\n")
    return "".join(sections)


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--check",
        action="store_true",
        help="fail if the generated bundle is missing or out of date",
    )
    args = parser.parse_args()
    expected = build_bundle()

    if args.check:
        if not OUTPUT.exists() or OUTPUT.read_text(encoding="utf-8") != expected:
            print(f"out of date: {OUTPUT.relative_to(ROOT)}", file=sys.stderr)
            return 1
        print(f"verified {OUTPUT.relative_to(ROOT)}")
        return 0

    OUTPUT.parent.mkdir(parents=True, exist_ok=True)
    OUTPUT.write_text(expected, encoding="utf-8")
    print(f"wrote {OUTPUT.relative_to(ROOT)}")
    return 0


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