"""Local draft creation with a persistent idempotency key. Python 3.11+."""
import argparse
import json
import sqlite3


class PayloadConflict(ValueError):
    pass


def connect(path):
    options = {"isolation_level": None, "timeout": 5.0}
    if hasattr(sqlite3, "LEGACY_TRANSACTION_CONTROL"):
        options["autocommit"] = sqlite3.LEGACY_TRANSACTION_CONTROL
    return sqlite3.connect(path, **options)


def initialize(path):
    db = connect(path)
    try:
        db.executescript("""
            CREATE TABLE IF NOT EXISTS drafts (
                id INTEGER PRIMARY KEY,
                body TEXT NOT NULL
            );
            CREATE TABLE IF NOT EXISTS events (
                event_id TEXT PRIMARY KEY NOT NULL,
                payload TEXT NOT NULL,
                result TEXT NOT NULL
            );
        """)
    finally:
        db.close()


def create_draft(path, event_id, payload):
    if not isinstance(event_id, str) or not event_id.strip():
        raise ValueError("event_id must be a nonempty string")
    if (not isinstance(payload, dict) or set(payload) != {"body"}
            or not isinstance(payload["body"], str)):
        raise ValueError("payload must contain only a string body")
    canonical = json.dumps(payload, sort_keys=True, separators=(",", ":"),
                           ensure_ascii=False, allow_nan=False)
    db = connect(path)
    try:
        db.execute("BEGIN IMMEDIATE")
        existing = db.execute(
            "SELECT payload, result FROM events WHERE event_id = ?",
            (event_id,),
        ).fetchone()
        if existing is not None:
            if existing[0] != canonical:
                raise PayloadConflict("event_id already used with a different payload")
            result = json.loads(existing[1])
        else:
            cursor = db.execute("INSERT INTO drafts(body) VALUES (?)", (payload["body"],))
            result = {"draft_id": cursor.lastrowid, "status": "draft"}
            db.execute("INSERT INTO events(event_id, payload, result) VALUES (?, ?, ?)",
                       (event_id, canonical, json.dumps(result)))
        db.execute("COMMIT")
        return result
    except BaseException:
        if db.in_transaction:
            db.execute("ROLLBACK")
        raise
    finally:
        db.close()


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("database")
    parser.add_argument("event_id")
    parser.add_argument("body")
    args = parser.parse_args()
    initialize(args.database)
    try:
        print(json.dumps(create_draft(args.database, args.event_id, {"body": args.body})))
    except PayloadConflict as exc:
        parser.exit(2, f"Conflict: {exc}\n")


if __name__ == "__main__":
    main()
