class Transcript:
    """Educational event contract; not a client for any real API."""
    def __init__(self):
        self.parts = {}

    def apply(self, event):
        key, revision, text, final = [event[x] for x in ("segment_id", "revision", "text", "is_final")]
        if not isinstance(key, str) or not key or type(revision) is not int or revision < 0:
            raise ValueError("Bad segment or revision")
        if not isinstance(text, str) or type(final) is not bool:
            raise ValueError("Bad text or final flag")
        old = self.parts.get(key)
        if old:
            if revision < old["revision"]:
                return  # Stale valid event: ignore even after finalization.
            if revision == old["revision"]:
                if event != old:
                    raise ValueError("Same-revision event conflict")
                return  # Exact duplicate: idempotent before or after final.
            if old["is_final"]:
                raise ValueError("Higher revision after final")
        self.parts[key] = dict(event)

    def render(self):
        return [{"segment_id": key, "text": value["text"], "is_final": value["is_final"]}
                for key, value in self.parts.items()]


def expect_rejection(transcript, event, name):
    before = {key: dict(value) for key, value in transcript.parts.items()}
    try:
        transcript.apply(event)
    except ValueError:
        assert transcript.parts == before
        print(name + "=True")
    else:
        raise AssertionError(name + " did not reject the event")


if __name__ == "__main__":
    t = Transcript()
    first = {"segment_id": "s1", "revision": 1, "text": "برای شنبه", "is_final": False}
    interim = {"segment_id": "s1", "revision": 2, "text": "برای سه‌شنبه", "is_final": False}
    final = {"segment_id": "s1", "revision": 3, "text": "برای سه‌شنبه می‌خواهم", "is_final": True}
    t.apply(first)
    t.apply(interim)
    t.apply(dict(interim))
    assert t.parts["s1"] == interim
    print("exact_interim_duplicate_idempotent=True")
    expect_rejection(t, {**interim, "text": "شنبه"}, "interim_same_revision_text_conflict_rejected")
    expect_rejection(t, {**interim, "is_final": True}, "interim_same_revision_final_flag_conflict_rejected")
    t.apply(first)
    assert t.parts["s1"] == interim
    print("stale_interim_ignored_before_final=True")
    t.apply(final)
    assert t.parts["s1"] == final
    print("higher_revision_can_finalize_interim=True")
    t.apply(first)
    t.apply(interim)
    assert t.parts["s1"] == final
    print("stale_partial_replay_after_final_ignored=True")
    t.apply(dict(final))
    assert t.parts["s1"] == final
    print("exact_final_duplicate_idempotent=True")
    expect_rejection(t, {**final, "text": "شنبه"}, "final_same_revision_conflict_rejected")
    expect_rejection(t, {**final, "revision": 4}, "higher_revision_after_final_rejected")
    assert len(t.render()) == 1 and t.render()[0]["text"] == final["text"]
    print(t.render())
