# tests/test_agent_guard_warnings.py
import warnings
import pytest
from llm_guard.scoring.agent_guard import AgentGuard

FACTOID_QUESTIONS = [
    "Who invented the telephone?",
    "What is the capital of France?",
    "When was the Eiffel Tower built?",
    "Where is the Great Barrier Reef located?",
    "Who wrote Hamlet?",
]

MULTI_HOP_QUESTIONS = [
    "What film did the director of Inception make after it was released?",
    "Compare the economic policies of Roosevelt and Hoover.",
    "Which country borders both Germany and France, and what is its capital?",
    "How did the 2008 financial crisis affect employment in Detroit?",
]

@pytest.mark.parametrize("q", FACTOID_QUESTIONS)
def test_factoid_warning_emitted(q):
    guard = AgentGuard()
    steps = [{"action_type": "Search", "thought": "Let me look this up.", "observation": "Some result."}]
    with warnings.catch_warnings(record=True) as w:
        warnings.simplefilter("always")
        guard.score_chain(q, steps, "Some answer")
    factoid_warnings = [x for x in w if "factoid" in str(x.message).lower() or "near-random" in str(x.message).lower()]
    assert len(factoid_warnings) == 1, f"Expected 1 factoid warning for '{q}', got {len(factoid_warnings)}"

@pytest.mark.parametrize("q", MULTI_HOP_QUESTIONS)
def test_no_factoid_warning_for_multi_hop(q):
    guard = AgentGuard()
    steps = [
        {"action_type": "Search", "thought": "Step 1", "observation": "Obs 1"},
        {"action_type": "Search", "thought": "Step 2", "observation": "Obs 2"},
    ]
    with warnings.catch_warnings(record=True) as w:
        warnings.simplefilter("always")
        guard.score_chain(q, steps, "Some answer")
    factoid_warnings = [x for x in w if "factoid" in str(x.message).lower() or "near-random" in str(x.message).lower()]
    assert len(factoid_warnings) == 0, f"Got unexpected factoid warning for '{q}'"

def test_factoid_warning_text_mentions_auroc():
    guard = AgentGuard()
    steps = [{"action_type": "Search", "thought": "look", "observation": "x"}]
    with warnings.catch_warnings(record=True) as w:
        warnings.simplefilter("always")
        guard.score_chain("Who invented the telephone?", steps, "Bell")
    assert any("0.52" in str(x.message) or "AUROC" in str(x.message) for x in w)


from llm_guard.verification.comprehensive_math_verifier import ComprehensiveMathVerifier
from llm_guard.verification.math_verifier import MathVerifier


class TestMathBackend:
    def test_default_backend_is_comprehensive(self):
        """Default AgentGuard should use ComprehensiveMathVerifier (no exec)."""
        guard = AgentGuard()
        # Force init of math verifier by scoring a math chain
        steps = [{"action_type": "Search", "thought": "15% of 240 = 36", "observation": "36"}]
        guard.score_chain("What is 15% of 240?", steps, "36")
        assert isinstance(guard._math_verifier, ComprehensiveMathVerifier), (
            f"Expected ComprehensiveMathVerifier, got {type(guard._math_verifier)}"
        )

    def test_use_math_exec_true_uses_math_verifier(self):
        """opt-in use_math_exec=True should use MathVerifier (subprocess)."""
        guard = AgentGuard(use_math_exec=True)
        steps = [{"action_type": "Search", "thought": "15% of 240 = 36", "observation": "36"}]
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            guard.score_chain("What is 15% of 240?", steps, "36")
        assert isinstance(guard._math_verifier, MathVerifier), (
            f"Expected MathVerifier, got {type(guard._math_verifier)}"
        )
        deprecation_warnings = [x for x in w if issubclass(x.category, DeprecationWarning)]
        assert len(deprecation_warnings) == 1, "Expected DeprecationWarning for use_math_exec=True"

    def test_math_score_unchanged_comprehensive(self):
        """ComprehensiveMathVerifier backend should correctly score a simple geometry problem."""
        guard = AgentGuard()
        # Use a geometry problem that ComprehensiveMathVerifier can fully verify (returns 0.10)
        # "15% of 240" falls into ComprehensiveMathVerifier's 'algebra' category but is
        # unverifiable (0.50) — geometry problems are fully verifiable (0.10 for correct).
        steps = [{"action_type": "Calculate", "thought": "Area = pi * r^2 = pi * 9 = 28.27", "observation": "28.27"}]
        result = guard.score_chain("What is the area of a circle with radius 3?", steps, "28.27")
        math_risk = result.behavioral_components.get("math_verified_risk")
        assert math_risk is not None
        assert math_risk <= 0.15, f"Expected low risk for correct answer, got {math_risk}"
