from fastapi import HTTPException
from fastapi.testclient import TestClient

from app.models.search import RetrievalChunkResult, RetrievalSearchResponse
from tests.conftest import TRUSTED_HEADERS


def test_retrieval_search_returns_results(monkeypatch):
    from app.main import app
    from app.services import retrieval_service as retrieval_module

    async def _fake_search(body, ctx):
        return RetrievalSearchResponse(
            results=[
                RetrievalChunkResult(
                    file_path="src/auth/middleware.ts",
                    start_line=10,
                    end_line=42,
                    score=0.87,
                    chunk_hash="sha256:deadbeef",
                    chunk_id="chk_001",
                    snippet="export function authMiddleware() { ... }",
                    source_type="repo_code",
                )
            ],
            request_id=ctx.request_id,
        )

    monkeypatch.setattr(retrieval_module.retrieval_service, "search", _fake_search)

    client = TestClient(app)
    response = client.post(
        "/api/v1/retrieval/search",
        headers=TRUSTED_HEADERS,
        json={
            "repo_ids": ["lucos:ws:abc123"],
            "query": "auth middleware",
        },
    )

    assert response.status_code == 200
    body = response.json()
    assert body["request_id"] == "req-test"
    assert len(body["results"]) == 1
    assert body["results"][0]["chunk_id"] == "chk_001"


def test_retrieval_search_denies_repo_without_acl(monkeypatch):
    from app.main import app
    from app.services import retrieval_service as retrieval_module

    async def _unexpected_search(body, ctx):
        raise AssertionError("search should not run")

    monkeypatch.setattr(retrieval_module.retrieval_service, "search", _unexpected_search)

    client = TestClient(app)
    response = client.post(
        "/api/v1/retrieval/search",
        headers={**TRUSTED_HEADERS, "X-Repo-Ids": "lucos:ws:allowed"},
        json={
            "repo_ids": ["lucos:ws:blocked"],
            "query": "auth middleware",
        },
    )

    assert response.status_code == 403


def test_retrieval_search_propagates_upstream_error(monkeypatch):
    from app.main import app
    from app.services import retrieval_service as retrieval_module

    async def _fake_search(body, ctx):
        raise HTTPException(
            status_code=502,
            detail={"code": "RETRIEVAL_UPSTREAM_ERROR"},
        )

    monkeypatch.setattr(retrieval_module.retrieval_service, "search", _fake_search)

    client = TestClient(app)
    response = client.post(
        "/api/v1/retrieval/search",
        headers=TRUSTED_HEADERS,
        json={
            "repo_ids": ["lucos:ws:abc123"],
            "query": "auth middleware",
        },
    )

    assert response.status_code == 502
    assert response.json()["detail"]["code"] == "RETRIEVAL_UPSTREAM_ERROR"
