"""Tests for divergence detection."""

from litmus.models import Trace, LLMCall, LLMRequest, LLMResponse, TraceMetadata
from litmus.diff import compare


def _make_trace(responses):
    """Make a trace with given response bodies."""
    trace = Trace(metadata=TraceMetadata())
    for body in responses:
        trace.add_step(LLMCall(
            request=LLMRequest(provider="anthropic", model="claude-sonnet-4-20250514", method="POST", path="/v1/messages"),
            response=LLMResponse(status_code=200, body=body),
            latency_ms=100,
        ))
    trace.complete()
    return trace


class TestDivergenceDetection:
    def test_identical_traces(self):
        body = {"content": [{"type": "text", "text": "hello"}], "stop_reason": "end_turn"}
        t1 = _make_trace([body, body])
        t2 = _make_trace([body, body])

        result = compare(t1, t2)
        assert not result.diverged
        assert result.step_count_match
        assert result.final_output_match
        assert result.fidelity_score == 1.0

    def test_different_step_count(self):
        body = {"content": [{"type": "text", "text": "hello"}]}
        t1 = _make_trace([body, body])
        t2 = _make_trace([body])

        result = compare(t1, t2)
        assert result.diverged
        assert not result.step_count_match

    def test_different_final_output(self):
        body1 = {"content": [{"type": "text", "text": "hello"}], "stop_reason": "end_turn"}
        body2 = {"content": [{"type": "text", "text": "goodbye"}], "stop_reason": "end_turn"}
        t1 = _make_trace([body1])
        t2 = _make_trace([body2])

        result = compare(t1, t2)
        assert result.diverged
        assert not result.final_output_match

    def test_different_tool_calls(self):
        body1 = {"content": [{"type": "tool_use", "name": "calculate", "input": {"x": 1}}], "stop_reason": "tool_use"}
        body2 = {"content": [{"type": "tool_use", "name": "get_weather", "input": {"city": "NYC"}}], "stop_reason": "tool_use"}
        t1 = _make_trace([body1])
        t2 = _make_trace([body2])

        result = compare(t1, t2)
        assert result.diverged
        # Should detect different tool calls
        tool_diffs = [d for d in result.diffs if d.field == "tool_calls"]
        assert len(tool_diffs) > 0

    def test_empty_traces(self):
        t1 = _make_trace([])
        t2 = _make_trace([])
        result = compare(t1, t2)
        assert not result.diverged
