#!/usr/bin/env python3
"""Surgically propagate credential-routing instructions to local repos.

Writes `.claude/rules/credential-routing.md`, inserts the section into AGENTS.md
(if missing), and adds the CLAUDE.md @include — without overwriting other
custom rules or repo-specific AGENTS.md extensions below REPO-AGENTS-EXTENSIONS.

Usage:
    python3 scripts/propagate_credential_routing.py              # all /home/worsch repos with AGENTS.md
    python3 scripts/propagate_credential_routing.py activity-core issue-core ops-warden
"""
from __future__ import annotations

import re
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent
TEMPLATE_DIR = ROOT / "scripts" / "project_rules"
WORKSPACE = Path("/home/worsch")
EXTENSION_MARKER = "<!-- REPO-AGENTS-EXTENSIONS -->"
SECTION_HEADING = "## Credential and access routing"
CLAUDE_INCLUDE = "@.claude/rules/credential-routing.md"


def render(template: str, values: dict[str, str]) -> str:
    for key, value in values.items():
        template = template.replace("{" + key + "}", value)
    return template


def repo_values(repo_path: Path) -> dict[str, str]:
    slug = repo_path.name
    prefix = slug.split("-", 1)[0].upper()
    return {
        "PROJECT_NAME": slug,
        "PROJECT_DESCRIPTION": slug,
        "DOMAIN": "",
        "TOPIC_ID": "(none)",
        "REPO_SLUG": slug,
        "WP_PREFIX": prefix,
    }


def insert_credential_section(agents_text: str, cred_section: str) -> str:
    """Insert general credential routing before repo-specific or workplan sections."""
    if SECTION_HEADING in agents_text:
        return agents_text
    block = "\n---\n\n" + cred_section.strip()
    for anchor in (
        "\n---\n\n## Issue-core emission",
        "\n---\n\n## REST ingestion API key",
        "\n---\n\n## Workplan Convention",
        "\n## Workplan Convention",
    ):
        if anchor in agents_text:
            return agents_text.replace(anchor, block + anchor, 1)
    return agents_text.rstrip() + block + "\n"


def patch_claude_md(claude_path: Path) -> bool:
    if not claude_path.exists():
        return False
    text = claude_path.read_text(encoding="utf-8")
    if CLAUDE_INCLUDE in text:
        return False
    if "@.claude/rules/agents.md" in text:
        text = text.replace(
            "@.claude/rules/agents.md",
            f"{CLAUDE_INCLUDE}\n@.claude/rules/agents.md",
        )
    else:
        text = text.rstrip() + "\n" + CLAUDE_INCLUDE + "\n"
    claude_path.write_text(text, encoding="utf-8")
    return True


def discover_repos(slugs: list[str] | None) -> list[Path]:
    if slugs:
        return [WORKSPACE / slug for slug in slugs if (WORKSPACE / slug).is_dir()]
    return sorted(
        p.parent
        for p in WORKSPACE.glob("*/AGENTS.md")
        if p.parent.is_dir() and not p.parent.name.startswith(".")
    )


def main(argv: list[str]) -> int:
    slugs = argv[1:] if len(argv) > 1 else None
    cred_template = (TEMPLATE_DIR / "credential-routing.template").read_text(encoding="utf-8")
    agents_template = (TEMPLATE_DIR / "agents-codex.template").read_text(encoding="utf-8")

    cred_rule_template = (
        "# Credential and access routing\n\n"
        + cred_template.lstrip().removeprefix("## Credential and access routing\n\n")
    )

    updated: list[str] = []
    for repo_path in discover_repos(slugs):
        values = repo_values(repo_path)
        cred_section = render(cred_template, values)

        rules_dir = repo_path / ".claude" / "rules"
        rules_dir.mkdir(parents=True, exist_ok=True)
        (rules_dir / "credential-routing.md").write_text(
            render(cred_rule_template, values), encoding="utf-8"
        )

        agents_path = repo_path / "AGENTS.md"
        if agents_path.exists():
            agents_text = agents_path.read_text(encoding="utf-8")
            if SECTION_HEADING not in agents_text:
                agents_path.write_text(
                    insert_credential_section(agents_text, cred_section),
                    encoding="utf-8",
                )
                updated.append(f"{repo_path.name}\tAGENTS.md (insert)")
        else:
            body = render(agents_template, {**values, "CREDENTIAL_ROUTING": cred_section})
            agents_path.write_text(body, encoding="utf-8")
            updated.append(f"{repo_path.name}\tAGENTS.md (new)")

        if patch_claude_md(repo_path / "CLAUDE.md"):
            updated.append(f"{repo_path.name}\tCLAUDE.md")

        if f"{repo_path.name}\tcredential-routing.md" not in updated:
            updated.append(f"{repo_path.name}\tcredential-routing.md")

    print(f"Propagated to {len(discover_repos(slugs))} repo(s):")
    for line in updated:
        print(f"  {line}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main(sys.argv))