from __future__ import annotations

from pathlib import Path

from tests.pipeline_setup_v3.core.artifacts import SummaryComposer
from tests.pipeline_setup_v3.core.models import CaseExpectations, LlmExpectation, RetrievalExpectation, RouterExpectation, V3Case
from tests.pipeline_setup_v3.core.validators import CaseValidator


def test_direct_symbol_test_hits_allows_related_context_when_symbol_not_in_rows() -> None:
    case = V3Case(
        case_id="negative-find-tests",
        runner="agent_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"},
            }
        ]
    }

    assert CaseValidator().validate(case, actual, details) == []


def test_llm_contains_and_excludes_checks() -> None:
    case = V3Case(
        case_id="llm-quality",
        runner="agent_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.",
    }

    assert CaseValidator().validate(case, actual, {}) == []


def test_summary_includes_token_usage_column() -> None:
    case = V3Case(
        case_id="llm-quality",
        runner="agent_runtime",
        mode="full_chain",
        query="Где health endpoint?",
        source_file=Path("cases.yaml"),
    )
    result_text = SummaryComposer().compose([
        type(
            "Result",
            (),
            {
                "case": case,
                "actual": {"sub_intent": "FIND_ENTRYPOINTS"},
                "details": {"token_usage": {"tokens_in_estimate": 321}, "rag_rows": []},
                "passed": True,
                "mismatches": [],
            },
        )()
    ])

    assert "Tokens" in result_text
    assert "321" in result_text
