"""
Comprehensive tests for headline_generator module.
Tests headline generation with LLM integration and edge cases.
"""

from unittest.mock import patch


class TestGenerateHeadline:
    """Tests for generate_headline function."""

    @patch(
        "local_deep_research.news.utils.headline_generator._generate_with_llm"
    )
    def test_returns_llm_headline_when_successful(self, mock_llm_gen):
        """Test returns LLM-generated headline when successful."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        mock_llm_gen.return_value = (
            "AI Breakthrough: New System Achieves Human-Level Performance"
        )

        result = generate_headline(
            "AI news", findings="Major AI development announced"
        )

        assert (
            result
            == "AI Breakthrough: New System Achieves Human-Level Performance"
        )

    @patch(
        "local_deep_research.news.utils.headline_generator._generate_with_llm"
    )
    def test_returns_failure_message_when_llm_fails(self, mock_llm_gen):
        """Test returns failure message when LLM fails."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        mock_llm_gen.return_value = None

        result = generate_headline("AI news", findings="Some findings")

        assert result == "[Headline generation failed]"

    @patch(
        "local_deep_research.news.utils.headline_generator._generate_with_llm"
    )
    def test_passes_query_to_llm_generator(self, mock_llm_gen):
        """Test passes query to LLM generator."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        mock_llm_gen.return_value = "Test Headline"

        generate_headline("Technology breakthroughs 2024", findings="Test")

        mock_llm_gen.assert_called_once()
        args = mock_llm_gen.call_args[0]
        assert args[0] == "Technology breakthroughs 2024"

    @patch(
        "local_deep_research.news.utils.headline_generator._generate_with_llm"
    )
    def test_passes_findings_to_llm_generator(self, mock_llm_gen):
        """Test passes findings to LLM generator."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        mock_llm_gen.return_value = "Test Headline"

        generate_headline("query", findings="Important research findings here")

        mock_llm_gen.assert_called_once()
        args = mock_llm_gen.call_args[0]
        assert args[1] == "Important research findings here"

    @patch(
        "local_deep_research.news.utils.headline_generator._generate_with_llm"
    )
    def test_passes_max_length_to_llm_generator(self, mock_llm_gen):
        """Test passes max_length to LLM generator."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        mock_llm_gen.return_value = "Test"

        generate_headline("query", findings="data", max_length=50)

        mock_llm_gen.assert_called_once()
        args = mock_llm_gen.call_args[0]
        assert args[2] == 50

    @patch(
        "local_deep_research.news.utils.headline_generator._generate_with_llm"
    )
    def test_default_max_length_is_100(self, mock_llm_gen):
        """Test default max_length is 100."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        mock_llm_gen.return_value = "Test"

        generate_headline("query", findings="data")

        args = mock_llm_gen.call_args[0]
        assert args[2] == 100

    @patch(
        "local_deep_research.news.utils.headline_generator._generate_with_llm"
    )
    def test_empty_findings_allowed(self, mock_llm_gen):
        """Test empty findings is allowed."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        mock_llm_gen.return_value = None

        result = generate_headline("query", findings="")

        assert result == "[Headline generation failed]"


class TestGenerateWithLLMBehavior:
    """Tests for _generate_with_llm behavior through the public API."""

    def test_returns_none_without_findings(self):
        """Test returns None when no findings provided."""
        from local_deep_research.news.utils.headline_generator import (
            _generate_with_llm,
        )

        # Without findings, should return None (no LLM call needed)
        result = _generate_with_llm("query", "", 100)

        assert result is None

    def test_function_exists_and_is_callable(self):
        """Test _generate_with_llm function exists and is callable."""
        from local_deep_research.news.utils.headline_generator import (
            _generate_with_llm,
        )

        assert callable(_generate_with_llm)

    def test_accepts_three_parameters(self):
        """Test accepts query, findings, max_length, and the optional
        settings_snapshot parameter (added so background news jobs can
        thread the egress policy into get_llm)."""
        from local_deep_research.news.utils.headline_generator import (
            _generate_with_llm,
        )
        import inspect

        sig = inspect.signature(_generate_with_llm)
        params = list(sig.parameters.keys())

        assert "query" in params
        assert "findings" in params
        assert "max_length" in params
        # settings_snapshot is optional (defaults to None) so existing
        # callers keep working.
        assert "settings_snapshot" in params
        assert sig.parameters["settings_snapshot"].default is None

    def test_returns_none_for_empty_string_findings(self):
        """Test returns None for empty string findings."""
        from local_deep_research.news.utils.headline_generator import (
            _generate_with_llm,
        )

        result = _generate_with_llm("any query", "", 100)

        assert result is None

    def test_handles_whitespace_only_findings(self):
        """Test handles whitespace-only findings."""
        from local_deep_research.news.utils.headline_generator import (
            _generate_with_llm,
        )

        # This may trigger LLM or return None depending on implementation
        result = _generate_with_llm("query", "   ", 100)

        # Result should be None or a string
        assert result is None or isinstance(result, str)


class TestHeadlineGeneratorEdgeCases:
    """Edge case tests for headline generator."""

    @patch(
        "local_deep_research.news.utils.headline_generator._generate_with_llm"
    )
    def test_handles_unicode_in_query(self, mock_llm_gen):
        """Test handles unicode characters in query."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        mock_llm_gen.return_value = "International News"

        result = generate_headline("日本語のニュース", findings="Content")

        assert result == "International News"
        args = mock_llm_gen.call_args[0]
        assert args[0] == "日本語のニュース"

    @patch(
        "local_deep_research.news.utils.headline_generator._generate_with_llm"
    )
    def test_handles_unicode_in_findings(self, mock_llm_gen):
        """Test handles unicode characters in findings."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        mock_llm_gen.return_value = "Test"

        result = generate_headline("query", findings="Données en français")

        assert result == "Test"

    @patch(
        "local_deep_research.news.utils.headline_generator._generate_with_llm"
    )
    def test_handles_very_long_query(self, mock_llm_gen):
        """Test handles very long query string."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        mock_llm_gen.return_value = "Summary"

        long_query = "A" * 10000
        result = generate_headline(long_query, findings="data")

        assert result == "Summary"

    @patch(
        "local_deep_research.news.utils.headline_generator._generate_with_llm"
    )
    def test_handles_newlines_in_findings(self, mock_llm_gen):
        """Test handles newlines in findings."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        mock_llm_gen.return_value = "Summary"

        result = generate_headline("query", findings="Line1\nLine2\nLine3")

        assert result == "Summary"

    @patch(
        "local_deep_research.news.utils.headline_generator._generate_with_llm"
    )
    def test_handles_special_characters_in_findings(self, mock_llm_gen):
        """Test handles special characters in findings."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        mock_llm_gen.return_value = "News"

        result = generate_headline(
            "query", findings="<script>alert('test')</script>"
        )

        assert result == "News"

    def test_handles_none_result_from_llm(self):
        """Test handles None result from _generate_with_llm."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        # When LLM fails (returns None), generate_headline returns failure message
        result = generate_headline("query", findings="")

        assert result == "[Headline generation failed]"


class TestHeadlineGeneratorImports:
    """Tests for module imports."""

    def test_imports_generate_headline(self):
        """Test generate_headline can be imported."""
        from local_deep_research.news.utils.headline_generator import (
            generate_headline,
        )

        assert generate_headline is not None
        assert callable(generate_headline)

    def test_imports_generate_with_llm(self):
        """Test _generate_with_llm can be imported."""
        from local_deep_research.news.utils.headline_generator import (
            _generate_with_llm,
        )

        assert _generate_with_llm is not None
        assert callable(_generate_with_llm)
