from __future__ import annotations

import sqlite3
from dataclasses import dataclass
from pathlib import Path


class ManagedConnection(sqlite3.Connection):
    """Commit or roll back, then release the SQLite handle on context exit."""

    def __exit__(self, exc_type, exc_value, traceback):
        try:
            return super().__exit__(exc_type, exc_value, traceback)
        finally:
            self.close()


@dataclass(frozen=True)
class SQLiteConnectionFactory:
    path: Path
    timeout_seconds: float = 20

    def connect(self) -> sqlite3.Connection:
        connection = sqlite3.connect(
            self.path,
            timeout=self.timeout_seconds,
            factory=ManagedConnection,
        )
        connection.row_factory = sqlite3.Row
        connection.execute("PRAGMA journal_mode=WAL")
        connection.execute("PRAGMA foreign_keys=ON")
        connection.execute("PRAGMA busy_timeout=20000")
        return connection
