#!/usr/bin/env python3
"""Regenerate the cloud-init copies of self-heal.sh from the canonical `ops/self-heal.sh`.

WHY THIS EXISTS
---------------
The agent cloud-init used to carry a HAND-WRITTEN COPY of the self-heal logic. It drifted,
silently, and the drift shipped bugs to every newly-provisioned agent:

  - PAPER-09 fixed the Created-container reaper in `ops/self-heal.sh` (2026-07-11) by
    adding an age guard. **The cloud-init copy never got it** — it still ran the old
    `created >= 1 && running == 0` test, the one PAPER-09 records as having fired 11
    times and killed healthy pipelines.
  - The unguarded `docker network prune -f` (which reddened mgf-logship #95 and
    mgf-hrb-cap #3/#5) lived in BOTH, and would have had to be fixed twice.

A copy of a truth is a second thing to forget. So there is now exactly one source —
`ops/self-heal.sh`, which already supports the agent host via `WOODPECKER_STACK_DIR` —
and this script stamps it into the cloud-inits. `test_ops_reconciler.py` asserts they
match, so they cannot drift again: a hand-edit of a cloud-init is a red test.

    python3 scripts/sync_self_heal.py            # rewrite the cloud-inits
    python3 scripts/sync_self_heal.py --check    # verify only (CI); exit 1 on drift
"""

from __future__ import annotations

import sys
from pathlib import Path

REPO = Path(__file__).resolve().parent.parent
CANONICAL = REPO / "ops" / "self-heal.sh"
TARGETS = (
    REPO / "examples" / "woodpecker-agent-cloud-init.yml",
    REPO
    / "src"
    / "mgf"
    / "cloud_provision"
    / "data"
    / "woodpecker"
    / "woodpecker-agent-cloud-init.yml",
)

MARKER = "  - path: /opt/woodpecker-agent/self-heal.sh\n"
INDENT = " " * 6


def rendered_block() -> str:
    """The canonical script, indented into the cloud-init `content: |` block."""
    body = CANONICAL.read_text(encoding="utf-8").rstrip("\n")
    lines = [(INDENT + ln) if ln.strip() else "" for ln in body.split("\n")]
    return MARKER + '    permissions: "0755"\n' + "    content: |\n" + "\n".join(lines) + "\n"


def splice(text: str, block: str) -> str:
    start = text.index(MARKER)
    # the block runs until the next top-level `write_files` entry or the next stanza
    rest = text[start + len(MARKER) :]
    end = start + len(MARKER)
    for line in rest.split("\n"):
        if line.startswith("  - path:") or (line and not line.startswith((" ", "\t"))):
            break
        end += len(line) + 1
    return text[:start] + block + text[end:]


def main() -> int:
    check = "--check" in sys.argv
    block = rendered_block()
    drifted = []

    for target in TARGETS:
        old = target.read_text(encoding="utf-8")
        new = splice(old, block)
        # the agent host lives at /opt/woodpecker-agent; the canonical script reads that
        # from WOODPECKER_STACK_DIR, so the cron MUST set it (default is /opt/woodpecker).
        new = new.replace(
            '(crontab -l 2>/dev/null; echo "*/5 * * * * /opt/woodpecker-agent/self-heal.sh") | crontab -',
            '(crontab -l 2>/dev/null; echo "*/5 * * * * WOODPECKER_STACK_DIR=/opt/woodpecker-agent /opt/woodpecker-agent/self-heal.sh") | crontab -',
        )
        if new != old:
            drifted.append(target.relative_to(REPO))
            if not check:
                target.write_text(new, encoding="utf-8")

    if check:
        if drifted:
            print("SELF-HEAL SYNC: DRIFT — the cloud-init copies do not match ops/self-heal.sh:")
            for d in drifted:
                print(f"  - {d}")
            print("\nRun: python3 scripts/sync_self_heal.py")
            return 1
        print("SELF-HEAL SYNC: OK — cloud-inits are byte-identical to ops/self-heal.sh")
        return 0

    if drifted:
        print(f"SELF-HEAL SYNC: rewrote {len(drifted)} cloud-init(s) from ops/self-heal.sh:")
        for d in drifted:
            print(f"  - {d}")
    else:
        print("SELF-HEAL SYNC: already in sync")
    return 0


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