"""Phase 2A (embedding-phase2a-1) — Qwen 후보 디스패처/쿼리 임베딩 단위 테스트."""

from __future__ import annotations

import pytest

from services.search import retrieval_service as rs


def test_resolve_qwen_backends():
    for slug in ("cand_qwen06", "cand_qwen4", "cand_qwen4m"):
        cfg = rs._resolve_backend(slug)
        assert cfg["docs_table"].startswith("documents_cand_qwen")
        assert cfg["chunks_table"].startswith("document_chunks_cand_qwen")
        assert cfg["embed_kind"] == "ollama"
        # 테이블명이 2단계 SQL allowlist 도 통과해야 함 (R2-B1)
        assert rs._VALID_DOCS_TABLE.match(cfg["docs_table"])
        assert rs._VALID_CHUNKS_TABLE.match(cfg["chunks_table"])
    assert rs._resolve_backend("baseline") is None
    with pytest.raises(ValueError):
        rs._resolve_backend("cand_unknown")


def test_qwen4m_has_mrl_dimensions():
    assert rs._resolve_backend("cand_qwen4m")["embed_dimensions"] == 1024
    assert "embed_dimensions" not in rs._resolve_backend("cand_qwen4")


class _FakeResp:
    def __init__(self, embs):
        self._embs = embs

    def raise_for_status(self):
        return None

    def json(self):
        return {"embeddings": self._embs}


class _FakeClient:
    """httpx.AsyncClient 대역 — post body 캡처."""

    captured: dict = {}

    def __init__(self, *a, **k):
        pass

    async def __aenter__(self):
        return self

    async def __aexit__(self, *a):
        return False

    async def post(self, url, json=None):
        _FakeClient.captured = {"url": url, "json": json}
        dim = (json or {}).get("dimensions") or 1024
        return _FakeResp([[0.1] * dim])


@pytest.mark.asyncio
async def test_ollama_query_embed_applies_instruct_prefix(monkeypatch):
    import httpx

    monkeypatch.setattr(httpx, "AsyncClient", _FakeClient)
    cfg = rs._resolve_backend("cand_qwen06")
    out = await rs._embed_query_via_ollama(cfg, "압력용기 수압시험")
    assert out is not None and len(out) == 1024
    body = _FakeClient.captured["json"]
    assert body["model"] == "qwen3-embedding:0.6b"
    assert body["input"][0].startswith(rs.QWEN3_QUERY_INSTRUCT)
    assert body["input"][0].endswith("압력용기 수압시험")
    assert "dimensions" not in body


@pytest.mark.asyncio
async def test_ollama_query_embed_mrl_dimensions(monkeypatch):
    import httpx

    monkeypatch.setattr(httpx, "AsyncClient", _FakeClient)
    cfg = rs._resolve_backend("cand_qwen4m")
    out = await rs._embed_query_via_ollama(cfg, "q")
    assert _FakeClient.captured["json"]["dimensions"] == 1024
    assert len(out) == 1024


@pytest.mark.asyncio
async def test_ollama_query_embed_failure_returns_none(monkeypatch):
    import httpx

    class _Boom(_FakeClient):
        async def post(self, url, json=None):
            raise httpx.ConnectError("down")

    monkeypatch.setattr(httpx, "AsyncClient", _Boom)
    cfg = rs._resolve_backend("cand_qwen06")
    assert await rs._embed_query_via_ollama(cfg, "q") is None
