"""Ensure repos track .claude/rules/ while ignoring other Claude Code local state."""

from __future__ import annotations

import re
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent
SNIPPET_PATH = ROOT / "scripts" / "project_rules" / "gitignore-claude.template"
MARKER = "# state-hub: track .claude/rules"
TRACK_RULE = "!.claude/rules/"
BLANKET_IGNORE_RE = re.compile(r"^\.claude/?\s*$", re.MULTILINE)


def load_snippet() -> str:
    text = SNIPPET_PATH.read_text(encoding="utf-8").strip()
    return f"{MARKER}\n{text}\n"


def snippet_present(text: str) -> bool:
    return TRACK_RULE in text


def ensure_claude_gitignore(gitignore_path: Path) -> bool:
    """Return True when the file was created or modified."""
    snippet = load_snippet()
    if gitignore_path.exists():
        text = gitignore_path.read_text(encoding="utf-8")
        if snippet_present(text):
            return False
        if BLANKET_IGNORE_RE.search(text):
            updated = BLANKET_IGNORE_RE.sub(snippet.rstrip(), text, count=1)
            if updated != text:
                gitignore_path.write_text(_ensure_trailing_newline(updated), encoding="utf-8")
                return True
        separator = "" if text.endswith("\n") or not text else "\n"
        gitignore_path.write_text(f"{text}{separator}\n{snippet}", encoding="utf-8")
        return True

    gitignore_path.write_text(snippet, encoding="utf-8")
    return True


def _ensure_trailing_newline(text: str) -> str:
    return text if text.endswith("\n") else f"{text}\n"


def main() -> int:
    import argparse

    parser = argparse.ArgumentParser(description="Ensure .gitignore tracks .claude/rules/.")
    parser.add_argument("path", type=Path, help="Repo root or .gitignore file path")
    args = parser.parse_args()

    target = args.path
    gitignore = target if target.name == ".gitignore" else target / ".gitignore"
    changed = ensure_claude_gitignore(gitignore)
    print(f"{'updated' if changed else 'ok'}: {gitignore}")
    return 0


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