"""Tests for LiveQASuite and ContextualRelevancyMetric empty context handling."""

from __future__ import annotations

from evalkit.metrics.answer_relevancy import AnswerRelevancyMetric
from evalkit.metrics.contextual_relevancy import ContextualRelevancyMetric
from evalkit.models import TestCase as EvalTestCase
from evalkit.suites import BUILTIN_SUITES, LiveQASuite
from evalkit.suites.base import EvaluationSuite


class TestLiveQASuite:
    def test_returns_evaluation_suite(self) -> None:
        suite = LiveQASuite()
        assert isinstance(suite, EvaluationSuite)

    def test_suite_name(self) -> None:
        suite = LiveQASuite()
        assert suite.name == "live_qa"

    def test_contains_two_metrics(self) -> None:
        suite = LiveQASuite()
        assert len(suite.metrics) == 2

    def test_contains_answer_relevancy(self) -> None:
        suite = LiveQASuite()
        metric_types = [type(m) for m in suite.metrics]
        assert AnswerRelevancyMetric in metric_types

    def test_contains_contextual_relevancy(self) -> None:
        suite = LiveQASuite()
        metric_types = [type(m) for m in suite.metrics]
        assert ContextualRelevancyMetric in metric_types

    def test_registered_in_builtin_suites(self) -> None:
        assert "live_qa" in BUILTIN_SUITES
        suite = BUILTIN_SUITES["live_qa"]()
        assert suite.name == "live_qa"

    def test_metric_names(self) -> None:
        suite = LiveQASuite()
        names = suite.metric_names()
        assert "answer_relevancy" in names
        assert "contextual_relevancy" in names


class TestContextualRelevancyEmptyContext:
    def test_returns_1_for_empty_context(self, mock_judge) -> None:
        metric = ContextualRelevancyMetric()
        tc = EvalTestCase(
            question="What is Python?",
            context=[],
            answer="Python is a language.",
        )
        score = metric.score(tc, mock_judge)
        assert score.score == 1.0
        assert score.passed is True
        assert "No context" in score.reason
        # Judge should NOT be called
        assert mock_judge.call_count == 0

    def test_calls_judge_for_non_empty_context(self, mock_judge) -> None:
        metric = ContextualRelevancyMetric()
        tc = EvalTestCase(
            question="What is Python?",
            context=["Python is a programming language."],
            answer="Python is a language.",
        )
        score = metric.score(tc, mock_judge)
        assert mock_judge.call_count == 1
        assert score.score == 0.8  # MockJudge default

    async def test_async_returns_1_for_empty_context(self, mock_judge) -> None:
        metric = ContextualRelevancyMetric()
        tc = EvalTestCase(
            question="Q",
            context=[],
            answer="A",
        )
        score = await metric.score_async(tc, mock_judge)
        assert score.score == 1.0
        assert score.passed is True
        assert mock_judge.call_count == 0
