import sqlite3
import tempfile
import unittest
from pathlib import Path
from workflow import PayloadConflict, create_draft, initialize


class WorkflowTests(unittest.TestCase):
    def setUp(self):
        self.temp = tempfile.TemporaryDirectory()
        self.addCleanup(self.temp.cleanup)
        self.path = Path(self.temp.name) / "test.sqlite3"
        initialize(self.path)

    def counts(self):
        with sqlite3.connect(self.path) as db:
            return tuple(db.execute(f"SELECT count(*) FROM {table}").fetchone()[0]
                         for table in ("drafts", "events"))

    def test_normal_creation(self):
        self.assertEqual(create_draft(self.path, "evt-42", {"body": "Hello"}),
                         {"draft_id": 1, "status": "draft"})
        self.assertEqual(self.counts(), (1, 1))

    def test_duplicate_returns_original_across_connections(self):
        first = create_draft(self.path, "evt-42", {"body": "Hello"})
        replay = create_draft(self.path, "evt-42", {"body": "Hello"})
        self.assertEqual(first, replay)
        self.assertEqual(self.counts(), (1, 1))

    def test_payload_conflict_leaves_original_unchanged(self):
        create_draft(self.path, "evt-42", {"body": "Hello"})
        with self.assertRaises(PayloadConflict):
            create_draft(self.path, "evt-42", {"body": "Changed"})
        self.assertEqual(self.counts(), (1, 1))
        with sqlite3.connect(self.path) as db:
            self.assertEqual(db.execute("SELECT body FROM drafts").fetchone()[0], "Hello")

    def test_failed_event_insert_rolls_back_draft(self):
        with sqlite3.connect(self.path) as db:
            db.execute("""CREATE TRIGGER fail_event BEFORE INSERT ON events
                          BEGIN SELECT RAISE(ABORT, 'injected failure'); END""")
        with self.assertRaises(sqlite3.IntegrityError):
            create_draft(self.path, "evt-42", {"body": "Hello"})
        self.assertEqual(self.counts(), (0, 0))

    def test_distinct_events_with_same_body_are_distinct(self):
        create_draft(self.path, "evt-42", {"body": "Hello"})
        result = create_draft(self.path, "evt-43", {"body": "Hello"})
        self.assertEqual(result["draft_id"], 2)
        self.assertEqual(self.counts(), (2, 2))


if __name__ == "__main__":
    unittest.main()
