import json
from dataclasses import dataclass

@dataclass
class GateResult:
    ok: bool
    reason: str


def check_resume_effect(events):
    """Require a consumed resume receipt to causally precede the first resumed effect."""
    consumed = [e for e in events if e.get("type") == "RESUME_CONSUMED"]
    effects = [e for e in events if e.get("type") == "RESUMED_EFFECT"]
    if len(consumed) != 1:
        return GateResult(False, "need exactly one RESUME_CONSUMED")
    if not effects:
        return GateResult(False, "no resumed effect")
    receipt = consumed[0]
    first = effects[0]
    if first.get("resume_id") != receipt.get("resume_id"):
        return GateResult(False, "effect is not linked to consumed receipt")
    if first.get("seq", -1) <= receipt.get("seq", -1):
        return GateResult(False, "effect does not follow receipt")
    return GateResult(True, "receipt-linked effect follows consumption")


def run():
    cases = {
        "fail_without_receipt": [{"type": "RESUMED_EFFECT", "resume_id": "r1", "seq": 2}],
        "fail_wrong_receipt": [
            {"type": "RESUME_CONSUMED", "resume_id": "r1", "seq": 4},
            {"type": "RESUMED_EFFECT", "resume_id": "r2", "seq": 5},
        ],
        "fail_effect_before": [
            {"type": "RESUMED_EFFECT", "resume_id": "r1", "seq": 3},
            {"type": "RESUME_CONSUMED", "resume_id": "r1", "seq": 4},
        ],
        "pass": [
            {"type": "RESUME_CONSUMED", "resume_id": "r1", "seq": 4},
            {"type": "RESUMED_EFFECT", "resume_id": "r1", "seq": 5},
        ],
    }
    expected = {"fail_without_receipt": False, "fail_wrong_receipt": False, "fail_effect_before": False, "pass": True}
    for name, events in cases.items():
        got = check_resume_effect(events).ok
        assert got == expected[name], (name, got, expected[name])
    print(json.dumps({"cases": len(cases), "passed": len(cases), "status": "PASS"}))

if __name__ == "__main__":
    run()
