from __future__ import annotations

import sqlite3
import tempfile
import unittest
from contextlib import closing
from pathlib import Path

import doc2md.history_db as history_db


class HistoryDbSchemaTest(unittest.TestCase):
    def test_schema_tables_and_columns(self) -> None:
        with tempfile.TemporaryDirectory() as tmpdir:
            db_path = Path(tmpdir) / "history.db"
            history_db.initialize_history_db(db_path)

            with closing(sqlite3.connect(db_path)) as conn:
                tables = {
                    row[0]
                    for row in conn.execute(
                        "SELECT name FROM sqlite_master WHERE type='table'"
                    )
                }
                expected_tables = {
                    "runs",
                    "inputs",
                    "outputs",
                    "warnings",
                    "timings",
                }
                self.assertTrue(expected_tables.issubset(tables))

                expected_columns = {
                    "runs": [
                        "id",
                        "started_at",
                        "finished_at",
                        "status",
                        "engine",
                        "format",
                        "exit_code",
                        "options_json",
                        "cwd",
                        "version",
                    ],
                    "inputs": [
                        "id",
                        "run_id",
                        "path",
                        "sha256",
                        "size_bytes",
                        "mtime_ns",
                    ],
                    "outputs": [
                        "id",
                        "run_id",
                        "path",
                        "bytes",
                        "sha256",
                        "written",
                    ],
                    "warnings": [
                        "id",
                        "run_id",
                        "code",
                        "message",
                    ],
                    "timings": [
                        "id",
                        "run_id",
                        "stage",
                        "duration_ms",
                        "meta_json",
                    ],
                }
                for table, columns in expected_columns.items():
                    with self.subTest(table=table):
                        info = conn.execute(f"PRAGMA table_info({table})").fetchall()
                        self.assertEqual([row[1] for row in info], columns)

    def test_foreign_keys_reference_runs(self) -> None:
        with tempfile.TemporaryDirectory() as tmpdir:
            db_path = Path(tmpdir) / "history.db"
            history_db.initialize_history_db(db_path)

            with closing(sqlite3.connect(db_path)) as conn:
                for table in ("inputs", "outputs", "warnings", "timings"):
                    with self.subTest(table=table):
                        fk = conn.execute(f"PRAGMA foreign_key_list({table})").fetchall()
                        self.assertTrue(fk)
                        self.assertEqual(fk[0][2], "runs")


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