"""Cohere rerank degradation paths — without-key + timeout fallback."""

import asyncio

import pytest
from langchain_core.documents import Document
from langchain_core.retrievers import BaseRetriever
from pydantic import PrivateAttr

from app.services.kb.retrievers.compression import build_compression_retriever


class _Stub(BaseRetriever):
    _docs: list = PrivateAttr()

    def __init__(self, docs):
        super().__init__()
        self._docs = docs

    def _get_relevant_documents(self, q, *, run_manager):
        return self._docs

    async def _aget_relevant_documents(self, q, *, run_manager):
        return self._docs


@pytest.mark.asyncio
async def test_no_cohere_key_returns_dense_top_k_with_degraded_marker():
    stub = _Stub(
        [
            Document(page_content=f"c{i}", metadata={"article_id": f"a{i}"})
            for i in range(10)
        ]
    )
    r = build_compression_retriever(stub, cohere_api_key=None)
    docs = await r.ainvoke("q")
    # Default KB_TOP_K_RERANK is 3.
    assert len(docs) == 3
    assert all(d.metadata.get("kb_rerank_degraded") for d in docs)


@pytest.mark.asyncio
async def test_no_cohere_key_preserves_input_order():
    stub = _Stub(
        [
            Document(page_content=f"c{i}", metadata={"article_id": f"a{i}"})
            for i in range(5)
        ]
    )
    r = build_compression_retriever(stub, cohere_api_key=None)
    docs = await r.ainvoke("q")
    assert [d.page_content for d in docs] == ["c0", "c1", "c2"]


def test_sync_fixture_compiles():
    # Tests sometimes run without pytest-asyncio — make sure no module-import
    # side effects break the cold path.
    assert build_compression_retriever
