"""Tests for SourceTermination."""

import pytest

from agentbyte.messages import AssistantMessage
from agentbyte.termination.source import SourceTermination
from agentbyte.termination.text_mention import TextMentionTermination


class TestSourceTermination:
    def test_terminates_on_matching_source(self):
        term = SourceTermination(source="reviewer")

        stop = term.check([AssistantMessage(content="Looks good.", source="reviewer")])
        assert stop is not None
        assert "reviewer" in stop.content
        assert stop.metadata["source"] == "reviewer"

    def test_no_termination_for_different_source(self):
        term = SourceTermination(source="reviewer")

        assert term.check([AssistantMessage(content="Looks good.", source="writer")]) is None

    def test_no_termination_for_empty_messages(self):
        term = SourceTermination(source="reviewer")
        assert term.check([]) is None

    def test_first_matching_message_triggers(self):
        term = SourceTermination(source="reviewer")

        msgs = [
            AssistantMessage(content="Keep going.", source="writer"),
            AssistantMessage(content="APPROVED", source="reviewer"),
            AssistantMessage(content="Extra message.", source="writer"),
        ]
        stop = term.check(msgs)
        assert stop is not None
        assert "APPROVED" in stop.metadata["message_snippet"]

    def test_snippet_truncated_to_100_chars(self):
        term = SourceTermination(source="agent")
        long_content = "x" * 200
        stop = term.check([AssistantMessage(content=long_content, source="agent")])
        assert stop is not None
        assert len(stop.metadata["message_snippet"]) == 100

    def test_composed_with_text_mention(self):
        """SourceTermination & TextMentionTermination — only fires when both conditions met."""
        from agentbyte.termination.composite import CompositeTermination

        combined = SourceTermination(source="reviewer") & TextMentionTermination("APPROVED")
        assert isinstance(combined, CompositeTermination)

        # Reviewer speaks but without APPROVED — should not terminate
        msgs_no_approval = [AssistantMessage(content="Needs more work.", source="reviewer")]
        assert combined.check(msgs_no_approval) is None

        # Reviewer speaks with APPROVED — should terminate
        msgs_approved = [AssistantMessage(content="APPROVED", source="reviewer")]
        stop = combined.check(msgs_approved)
        assert stop is not None

    def test_invalid_empty_source_raises(self):
        with pytest.raises(ValueError, match="source"):
            SourceTermination(source="")
