"""Tests for tsumugi.context module."""

from tsumugi.context import (
    compact_messages,
    estimate_conversation_tokens,
    estimate_message_tokens,
    estimate_tokens,
)


class TestEstimateTokens:
    def test_empty_string(self):
        assert estimate_tokens("") == 0

    def test_ascii_text(self):
        result = estimate_tokens("Hello World")  # 11 chars
        assert result > 0
        assert result < 20  # Reasonable upper bound

    def test_japanese_text(self):
        result = estimate_tokens("こんにちは世界")  # 7 chars, all non-ASCII
        assert result > 0

    def test_japanese_higher_than_ascii_per_char(self):
        # Japanese should estimate more tokens per character
        ascii_result = estimate_tokens("abcdefgh")  # 8 ASCII chars
        jp_result = estimate_tokens("あいうえおかきく")  # 8 Japanese chars
        assert jp_result > ascii_result

    def test_mixed_text(self):
        result = estimate_tokens("Hello こんにちは")
        assert result > 0


class TestEstimateMessageTokens:
    def test_string_content(self):
        msg = {"role": "user", "content": "Hello"}
        result = estimate_message_tokens(msg)
        assert result > 0

    def test_list_content_text(self):
        msg = {
            "role": "assistant",
            "content": [{"type": "text", "text": "Hello World"}],
        }
        result = estimate_message_tokens(msg)
        assert result > 4  # More than just role overhead

    def test_list_content_tool_use(self):
        msg = {
            "role": "assistant",
            "content": [
                {
                    "type": "tool_use",
                    "name": "read_file",
                    "input": {"file_path": "/tmp/test.txt"},
                }
            ],
        }
        result = estimate_message_tokens(msg)
        assert result > 4

    def test_empty_content(self):
        msg = {"role": "user", "content": ""}
        result = estimate_message_tokens(msg)
        assert result >= 4  # At least role overhead


class TestEstimateConversationTokens:
    def test_empty(self):
        result = estimate_conversation_tokens([])
        assert result["total"] == 0
        assert result["message_count"] == 0

    def test_with_system(self):
        result = estimate_conversation_tokens([], system_prompt="System prompt text")
        assert result["system"] > 0
        assert result["messages"] == 0
        assert result["total"] == result["system"]

    def test_with_messages(self):
        messages = [
            {"role": "user", "content": "Hello"},
            {"role": "assistant", "content": "Hi there!"},
        ]
        result = estimate_conversation_tokens(messages)
        assert result["messages"] > 0
        assert result["message_count"] == 2
        assert result["total"] == result["system"] + result["messages"]


class TestCompactMessages:
    def test_no_compact_when_few(self):
        messages = [
            {"role": "user", "content": "Hello"},
            {"role": "assistant", "content": "Hi"},
        ]
        result, info = compact_messages(messages, keep_recent=6)
        assert result == messages
        assert info == ""

    def test_compact_old_messages(self):
        messages = [
            {"role": "user", "content": f"Message {i}"}
            for i in range(10)
        ]
        result, info = compact_messages(messages, keep_recent=4)
        # Should have: summary + ack + 4 recent = 6
        assert len(result) == 6
        assert "要約" in result[0]["content"]
        assert "把握しました" in result[1]["content"]
        assert info != ""
        assert "メッセージを要約しました" in info

    def test_keeps_recent_intact(self):
        messages = [
            {"role": "user", "content": f"Msg-{i}"}
            for i in range(10)
        ]
        result, _ = compact_messages(messages, keep_recent=3)
        # Last 3 messages should be preserved
        assert result[-1]["content"] == "Msg-9"
        assert result[-2]["content"] == "Msg-8"
        assert result[-3]["content"] == "Msg-7"

    def test_truncates_long_text_in_summary(self):
        messages = [
            {"role": "user", "content": "A" * 500},
            *[{"role": "user", "content": f"recent-{i}"} for i in range(6)],
        ]
        result, _ = compact_messages(messages, keep_recent=6)
        summary = result[0]["content"]
        # The 500-char message should be truncated in the summary
        assert "..." in summary
