"""Local teaching experiment: two cooperating processes, one exclusive file.

Run: python cc05-reservation-demo.py
Uses only a temporary directory. No models, network, or service management.
Not a production lock manager: no crash recovery, leases or access control.
"""
import datetime
import json
import multiprocessing as mp
import os
from pathlib import Path
import platform
import tempfile


def worker(name, reservation, start, attempted, results):
    start.wait(timeout=20)
    try:
        with open(reservation, "x", encoding="utf-8") as stream:
            stream.write(name)
        outcome = "acquired"
    except FileExistsError:
        outcome = "busy"
    results.put({"worker": name, "outcome": outcome})
    # Keep the reservation until BOTH attempts finish; otherwise two sequential
    # acquisitions would be valid, and would not demonstrate a conflict.
    attempted.wait(timeout=20)


def main():
    ctx = mp.get_context("spawn")
    rounds = []
    with tempfile.TemporaryDirectory(prefix="l00p-reservation-demo-") as directory:
        root = Path(directory).resolve()
        assert root.parent == Path(tempfile.gettempdir()).resolve()
        for index in range(20):
            reservation = root / f"round-{index + 1}.lock"
            start, attempted = ctx.Barrier(2), ctx.Barrier(2)
            results = ctx.Queue()
            children = [ctx.Process(target=worker, args=(name, str(reservation), start, attempted, results)) for name in ("A", "B")]
            for child in children:
                child.start()
            observed = [results.get(timeout=30) for _ in children]
            for child in children:
                child.join(timeout=30)
                assert child.exitcode == 0, "Worker did not finish successfully"
            assert sorted(item["outcome"] for item in observed) == ["acquired", "busy"]
            winner = next(item["worker"] for item in observed if item["outcome"] == "acquired")
            assert reservation.read_text(encoding="utf-8") == winner
            rounds.append({"round": index + 1, "results": sorted(observed, key=lambda item: item["worker"]), "owner_record_preserved": True})
            # Parent owns the experiment directory; both workers have exited.
            reservation.unlink()
            results.close()
            results.join_thread()
    return {
        "checked_at": datetime.datetime.now(datetime.timezone.utc).isoformat(),
        "python": platform.python_version(), "os": platform.system(),
        "rounds": rounds, "passed": len(rounds),
        "scope": "Exclusive creation on this local temporary filesystem; cooperative Python workers, not AI agents. No crash recovery, network filesystem or production test."
    }


if __name__ == "__main__":
    print(json.dumps(main(), indent=2))
