"""Offline tutorial example: store an event once, without losing conflicts.

Input payloads are authenticated, size-limited bytes supplied by the caller.
This module does not verify signatures or execute event side effects.
"""
import hashlib
import sqlite3
from contextlib import closing


class EventConflict(ValueError):
    """An existing event identifier was reused with different payload bytes."""


def initialise(path):
    with closing(sqlite3.connect(path)) as connection:
        connection.execute("""
            CREATE TABLE IF NOT EXISTS inbox (
                source TEXT NOT NULL,
                event_id TEXT NOT NULL,
                payload BLOB NOT NULL,
                payload_sha256 TEXT NOT NULL,
                PRIMARY KEY (source, event_id)
            )
        """)
        connection.commit()


def record_event(path, source, event_id, payload, *, timeout=5.0):
    """Return 'stored' or 'duplicate' only after the database commit succeeds.

    Identifiers are namespaced by source. A duplicate means identical raw
    payload bytes, not merely equivalent parsed JSON. Conflicts and storage
    errors propagate to the caller; they must not become successful HTTP acks.
    """
    for name, value in (("source", source), ("event_id", event_id)):
        if not isinstance(value, str) or not value.strip():
            raise ValueError(f"{name} must be a nonempty string")
    if not isinstance(payload, bytes):
        raise TypeError("payload must be bytes")
    digest = hashlib.sha256(payload).hexdigest()

    # Each call owns its connection. BEGIN IMMEDIATE serialises the check and
    # insert against competing writers, including writers in another process.
    with closing(sqlite3.connect(path, timeout=timeout, isolation_level=None)) as connection:
        connection.execute("BEGIN IMMEDIATE")
        try:
            previous = connection.execute(
                "SELECT payload FROM inbox WHERE source=? AND event_id=?",
                (source, event_id),
            ).fetchone()
            if previous is not None:
                if previous[0] != payload:
                    raise EventConflict("event identifier has a different payload")
                result = "duplicate"
            else:
                connection.execute(
                    "INSERT INTO inbox (source, event_id, payload, payload_sha256) VALUES (?, ?, ?, ?)",
                    (source, event_id, payload, digest),
                )
                result = "stored"
            connection.commit()
            return result
        except BaseException:
            connection.rollback()
            raise


if __name__ == "__main__":
    import tempfile
    from pathlib import Path
    with tempfile.TemporaryDirectory() as directory:
        path = Path(directory) / "inbox.sqlite3"
        initialise(path)
        body = b'{"kind":"report.ready","report_id":"report-42"}'
        print(record_event(path, "example-provider", "evt-001", body))
        print(record_event(path, "example-provider", "evt-001", body))
