from __future__ import annotations

from pathlib import Path

from tests.pipeline_setup_v2.core.models import CaseExpectations, LlmExpectation, RetrievalExpectation, RouterExpectation, V2Case
from tests.pipeline_setup_v2.core.validators import CaseValidator


def test_direct_symbol_test_hits_allows_related_context_when_symbol_not_in_rows() -> None:
    case = V2Case(
        case_id="negative-find-tests",
        runner="runtime",
        mode="full_chain",
        query="Где тесты для WorkflowRuntimeFactory?",
        source_file=Path("cases.yaml"),
        expectations=CaseExpectations(
            router=RouterExpectation(intent="CODE_QA", sub_intent="FIND_TESTS"),
            retrieval=RetrievalExpectation(
                direct_symbol_test_hits_max=0,
                symbol_candidates_contain=("WorkflowRuntimeFactory",),
            ),
        ),
    )
    actual = {
        "intent": "CODE_QA",
        "sub_intent": "FIND_TESTS",
        "rag_count": 2,
        "symbol_candidates": ("WorkflowRuntimeFactory",),
        "layers": ("C2_DEPENDENCY_GRAPH",),
    }
    details = {
        "rag_rows": [
            {
                "path": "tests/test_business_control_actions.py",
                "title": "test_worker_wakes_up_with_configured_interval:dataflow_slice",
                "content": "ScenarioWorker.name",
                "metadata": {"is_test": True, "src_qname": "test_worker_wakes_up_with_configured_interval"},
            }
        ]
    }

    mismatches = CaseValidator().validate(case, actual, details)

    assert mismatches == []


def test_direct_symbol_test_hits_flags_direct_matches_in_test_rows() -> None:
    case = V2Case(
        case_id="negative-find-tests",
        runner="runtime",
        mode="full_chain",
        query="Где тесты для WorkflowRuntimeFactory?",
        source_file=Path("cases.yaml"),
        expectations=CaseExpectations(
            router=RouterExpectation(intent="CODE_QA", sub_intent="FIND_TESTS"),
            retrieval=RetrievalExpectation(
                direct_symbol_test_hits_max=0,
                symbol_candidates_contain=("WorkflowRuntimeFactory",),
            ),
        ),
    )
    actual = {
        "intent": "CODE_QA",
        "sub_intent": "FIND_TESTS",
        "rag_count": 1,
        "symbol_candidates": ("WorkflowRuntimeFactory",),
        "layers": ("C0_SOURCE_CHUNKS",),
    }
    details = {
        "rag_rows": [
            {
                "path": "tests/test_workflow_runtime_factory.py",
                "title": "test_workflow_runtime_factory_builds_runtime",
                "content": "WorkflowRuntimeFactory builds runtime",
                "metadata": {"is_test": True, "src_qname": "test_workflow_runtime_factory_builds_runtime"},
            }
        ]
    }

    mismatches = CaseValidator().validate(case, actual, details)

    assert mismatches == ["retrieval: expected direct symbol-linked test hits <= 0, got 1"]


def test_llm_contains_and_excludes_checks() -> None:
    case = V2Case(
        case_id="llm-quality",
        runner="runtime",
        mode="full_chain",
        query="Где health endpoint?",
        source_file=Path("cases.yaml"),
        expectations=CaseExpectations(
            router=RouterExpectation(intent="CODE_QA", sub_intent="FIND_ENTRYPOINTS"),
            llm=LlmExpectation(
                non_empty=True,
                contains_all=("GET /health",),
                excludes=("нет явных неподтвержденных кандидатов",),
            ),
        ),
    )
    actual = {
        "intent": "CODE_QA",
        "sub_intent": "FIND_ENTRYPOINTS",
        "rag_count": 3,
        "llm_answer": "GET /health объявлен в HttpControlAppFactory.",
    }

    mismatches = CaseValidator().validate(case, actual, {})

    assert mismatches == []
