"""Tests for LLM summarizer — mocked backend calls."""

from unittest.mock import patch, MagicMock
import json

from memotrail.extractors.llm_summarizer import LLMSummarizer


class TestLLMSummarizer:
    def test_default_model_ollama(self):
        s = LLMSummarizer(backend="ollama")
        assert s.model == "llama3.2"

    def test_default_model_openai(self):
        s = LLMSummarizer(backend="openai")
        assert s.model == "gpt-4o-mini"

    def test_default_model_anthropic(self):
        s = LLMSummarizer(backend="anthropic")
        assert s.model == "claude-haiku-4-5-20251001"

    def test_custom_model(self):
        s = LLMSummarizer(backend="ollama", model="mistral")
        assert s.model == "mistral"

    def test_unknown_backend_returns_none(self):
        s = LLMSummarizer(backend="unknown_backend")
        result = s.summarize([{"role": "user", "content": "test"}])
        assert result is None

    @patch("urllib.request.urlopen")
    def test_ollama_call(self, mock_urlopen):
        mock_resp = MagicMock()
        mock_resp.read.return_value = json.dumps({"response": "Summary of the session"}).encode()
        mock_resp.__enter__ = MagicMock(return_value=mock_resp)
        mock_resp.__exit__ = MagicMock(return_value=False)
        mock_urlopen.return_value = mock_resp

        s = LLMSummarizer(backend="ollama")
        result = s.summarize([
            {"role": "user", "content": "Fix the login bug"},
            {"role": "assistant", "content": "I fixed the bug in auth.py"},
        ])
        assert result == "Summary of the session"
        mock_urlopen.assert_called_once()

    @patch("urllib.request.urlopen")
    @patch.dict("os.environ", {"OPENAI_API_KEY": "test-key"})
    def test_openai_call(self, mock_urlopen):
        mock_resp = MagicMock()
        mock_resp.read.return_value = json.dumps({
            "choices": [{"message": {"content": "OpenAI summary"}}]
        }).encode()
        mock_resp.__enter__ = MagicMock(return_value=mock_resp)
        mock_resp.__exit__ = MagicMock(return_value=False)
        mock_urlopen.return_value = mock_resp

        s = LLMSummarizer(backend="openai")
        result = s.summarize([{"role": "user", "content": "test"}])
        assert result == "OpenAI summary"

    @patch("urllib.request.urlopen")
    @patch.dict("os.environ", {"ANTHROPIC_API_KEY": "test-key"})
    def test_anthropic_call(self, mock_urlopen):
        mock_resp = MagicMock()
        mock_resp.read.return_value = json.dumps({
            "content": [{"text": "Anthropic summary"}]
        }).encode()
        mock_resp.__enter__ = MagicMock(return_value=mock_resp)
        mock_resp.__exit__ = MagicMock(return_value=False)
        mock_urlopen.return_value = mock_resp

        s = LLMSummarizer(backend="anthropic")
        result = s.summarize([{"role": "user", "content": "test"}])
        assert result == "Anthropic summary"

    @patch.dict("os.environ", {}, clear=True)
    def test_openai_missing_key(self):
        # Remove key if it exists
        import os
        os.environ.pop("OPENAI_API_KEY", None)
        s = LLMSummarizer(backend="openai")
        result = s.summarize([{"role": "user", "content": "test"}])
        assert result is None

    def test_summarize_limits_input(self):
        """Verify that long messages get truncated before sending."""
        s = LLMSummarizer(backend="unknown_backend")
        messages = [{"role": "user", "content": "x" * 10000}] * 50
        # Should not raise even with huge input
        result = s.summarize(messages)
        assert result is None  # unknown backend
