"""Unit tests for the startup model invariant -- no real DB."""
from __future__ import annotations

import pathlib
import sys

import pytest

sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1]))

from app.startup import ModelInvariantError, validate_embed_model  # noqa: E402


class _FakeConn:
    def __init__(self, chunk_models: set, summary_embedding_models: set):
        self._chunk_models = chunk_models
        self._summary_embedding_models = summary_embedding_models

    async def fetch(self, query, *params):
        if "FROM document_chunk" in query:
            return [{"model": m} for m in self._chunk_models]
        if "FROM document_summary" in query:
            return [{"embedding_model": m} for m in self._summary_embedding_models]
        raise AssertionError(f"unexpected query: {query}")


class TestValidateEmbedModel:
    async def test_passes_when_model_present_in_both_tables(self):
        conn = _FakeConn(chunk_models={"bge-m3"}, summary_embedding_models={"bge-m3"})
        await validate_embed_model(conn, "bge-m3")  # must not raise

    async def test_fails_when_chunk_model_missing(self):
        conn = _FakeConn(chunk_models={"some-other-model"}, summary_embedding_models={"bge-m3"})
        with pytest.raises(ModelInvariantError, match="document_chunk"):
            await validate_embed_model(conn, "bge-m3")

    async def test_fails_when_chunk_table_empty(self):
        conn = _FakeConn(chunk_models=set(), summary_embedding_models={"bge-m3"})
        with pytest.raises(ModelInvariantError, match="document_chunk"):
            await validate_embed_model(conn, "bge-m3")

    async def test_fails_when_summary_embedding_model_missing(self):
        conn = _FakeConn(chunk_models={"bge-m3"}, summary_embedding_models={"some-other-model"})
        with pytest.raises(ModelInvariantError, match="document_summary"):
            await validate_embed_model(conn, "bge-m3")

    async def test_does_not_confuse_summary_writer_model_with_embedding_model(self):
        # Regression guard: document_summary.model is the LLM that WROTE the summary
        # (claude-haiku-4-5/gemma3:12b), never bge-m3 -- checking that column instead of
        # embedding_model would make this invariant impossible to satisfy.
        conn = _FakeConn(
            chunk_models={"bge-m3"},
            summary_embedding_models={"bge-m3"},
        )
        assert conn._summary_embedding_models == {"bge-m3"}
        await validate_embed_model(conn, "bge-m3")  # must not raise
