"""
tests/conftest.py
Common test fixtures.

Provides shared MockAIClient + PersistentHandler fixtures.
"""
import hashlib
import os

import pytest

# Disable auth for testing
os.environ["TRUSTMEM_AUTH_REQUIRED"] = "0"


class MockAIClient:
    """Test-only AI client with deterministic hash-based embeddings (768-dim)."""

    def embed(self, text: str) -> list[float]:
        h = hashlib.sha256(text.encode()).hexdigest()
        vec = [int(c, 16) / 15.0 for c in h]
        while len(vec) < 768:
            vec.extend(vec[: 768 - len(vec)])
        return vec[:768]

    def batch_embed(self, texts: list[str]) -> list[list[float]]:
        return [self.embed(t) for t in texts]

    def llm_judge(self, prompt: str) -> str:
        return '{"facts": [], "entities": []}'


class SmallMockAIClient:
    """Deterministic AI client with small (8-dim) normalized embeddings.

    Used by extraction/remember/KG tests where vector dimensionality
    doesn't matter but normalization is needed for cosine similarity.
    """

    def __init__(self, dim: int = 8):
        self._dim = dim

    def embed(self, text: str) -> list[float]:
        h = hash(text) & 0xFFFFFFFF
        vec = []
        for i in range(self._dim):
            val = ((h >> (i * 4)) & 0xF) / 15.0
            vec.append(val)
        norm = sum(v * v for v in vec) ** 0.5
        if norm > 0:
            vec = [v / norm for v in vec]
        return vec

    def batch_embed(self, texts: list[str]) -> list[list[float]]:
        return [self.embed(t) for t in texts]

    def llm_judge(self, prompt: str) -> str:
        return "no_contradiction"


@pytest.fixture
def mock_ai():
    """Provide a MockAIClient instance."""
    return MockAIClient()


@pytest.fixture
def handler(mock_ai):
    """Provide a PersistentHandler with in-memory stores."""
    from trustmem.handler.persistent import PersistentHandler

    h = PersistentHandler(
        database_url=":memory:",
        ai_client=mock_ai,
    )
    h.reset_stores()
    return h
