"""Tests for FactualityCheck."""

from __future__ import annotations

from unittest.mock import MagicMock, patch

import pytest

from ai_qa.checks.factuality import FactualityCheck
from ai_qa.core.context import Context


def test_factuality_check_name():
    """Test FactualityCheck has correct name."""
    check = FactualityCheck()
    assert check.name == "factuality"


def test_factuality_check_requires_llm():
    """Test FactualityCheck requires LLM."""
    check = FactualityCheck()
    assert check.requires_llm is True


@patch("ai_qa.checks.factuality.get_provider")
def test_factuality_check_accurate_output(mock_get_provider):
    """Test FactualityCheck with factually accurate output."""
    mock_provider = MagicMock()
    mock_provider.judge.return_value = {
        "score": 1.0,
        "evidence": "All facts are accurate and well-supported",
    }
    mock_get_provider.return_value = mock_provider

    check = FactualityCheck()
    ctx = Context(
        output="The Earth orbits the Sun",
        ground_truth="The Earth orbits the Sun",
        context=["The solar system consists of the Sun and orbiting planets"],
    )
    result = check.evaluate(ctx)

    assert result.passed is True
    assert result.score == 1.0


@patch("ai_qa.checks.factuality.get_provider")
def test_factuality_check_inaccurate_output(mock_get_provider):
    """Test FactualityCheck with factually inaccurate output."""
    mock_provider = MagicMock()
    mock_provider.judge.return_value = {
        "score": 0.1,
        "evidence": "Claim contradicts context: Earth does not orbit Venus",
    }
    mock_get_provider.return_value = mock_provider

    check = FactualityCheck()
    ctx = Context(
        output="The Earth orbits Venus",
        context=["The Earth orbits the Sun"],
    )
    result = check.evaluate(ctx)

    assert result.passed is False
    assert result.score == 0.1


@patch("ai_qa.checks.factuality.get_provider")
def test_factuality_check_with_ground_truth(mock_get_provider):
    """Test FactualityCheck uses ground truth for comparison."""
    mock_provider = MagicMock()
    mock_provider.judge.return_value = {"score": 0.8, "evidence": "Mostly accurate"}
    mock_get_provider.return_value = mock_provider

    check = FactualityCheck()
    ctx = Context(
        output="Water boils at approximately 100 degrees Celsius",
        ground_truth="Water boils at 100 degrees Celsius at sea level",
    )
    result = check.evaluate(ctx)

    assert result.score == 0.8


@patch("ai_qa.checks.factuality.get_provider")
def test_factuality_check_custom_threshold(mock_get_provider):
    """Test FactualityCheck with custom threshold."""
    mock_provider = MagicMock()
    mock_provider.judge.return_value = {"score": 0.75, "evidence": "Partially accurate"}
    mock_get_provider.return_value = mock_provider

    check = FactualityCheck(threshold=0.85)
    ctx = Context(output="Test output")
    result = check.evaluate(ctx)

    assert result.passed is False


@patch("ai_qa.checks.factuality.get_provider")
def test_factuality_check_without_context(mock_get_provider):
    """Test FactualityCheck without context."""
    mock_provider = MagicMock()
    mock_provider.judge.return_value = {"score": 0.9, "evidence": "OK"}
    mock_get_provider.return_value = mock_provider

    check = FactualityCheck()
    ctx = Context(output="The sky is blue")
    result = check.evaluate(ctx)

    assert result.passed is True
