"""
Tests for citation_handler.py

Tests cover:
- CitationHandler initialization
- Handler type selection
- Method delegation
"""

from unittest.mock import Mock, patch


class TestCitationHandlerInit:
    """Tests for CitationHandler initialization."""

    def test_default_handler_type(self):
        """Test default handler type is standard."""
        mock_llm = Mock()

        with patch(
            "local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            handler = CitationHandler(mock_llm)

            mock_handler_class.assert_called_once()
            assert handler._handler == mock_handler

    def test_explicit_standard_handler(self):
        """Test explicit standard handler type."""
        mock_llm = Mock()

        with patch(
            "local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            CitationHandler(mock_llm, handler_type="standard")

            mock_handler_class.assert_called_once()

    def test_forced_handler_type(self):
        """Test forced handler type."""
        mock_llm = Mock()

        with patch(
            "local_deep_research.citation_handlers.forced_answer_citation_handler.ForcedAnswerCitationHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            CitationHandler(mock_llm, handler_type="forced")

            mock_handler_class.assert_called_once()

    def test_browsecomp_handler_type(self):
        """Test browsecomp handler type maps to forced."""
        mock_llm = Mock()

        with patch(
            "local_deep_research.citation_handlers.forced_answer_citation_handler.ForcedAnswerCitationHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            CitationHandler(mock_llm, handler_type="browsecomp")

            mock_handler_class.assert_called_once()

    def test_precision_handler_type(self):
        """Test precision handler type."""
        mock_llm = Mock()

        with patch(
            "local_deep_research.citation_handlers.precision_extraction_handler.PrecisionExtractionHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            CitationHandler(mock_llm, handler_type="precision")

            mock_handler_class.assert_called_once()

    def test_simpleqa_handler_type(self):
        """Test simpleqa handler type maps to precision."""
        mock_llm = Mock()

        with patch(
            "local_deep_research.citation_handlers.precision_extraction_handler.PrecisionExtractionHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            CitationHandler(mock_llm, handler_type="simpleqa")

            mock_handler_class.assert_called_once()

    def test_unknown_handler_type_fallback(self):
        """Test unknown handler type falls back to standard."""
        mock_llm = Mock()

        with patch(
            "local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            CitationHandler(mock_llm, handler_type="unknown_type")

            # Called twice - once for unknown fallback
            assert mock_handler_class.call_count >= 1

    def test_handler_type_from_settings_snapshot(self):
        """Test handler type from settings snapshot."""
        mock_llm = Mock()
        settings_snapshot = {"citation.handler_type": "forced"}

        with patch(
            "local_deep_research.citation_handlers.forced_answer_citation_handler.ForcedAnswerCitationHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            CitationHandler(mock_llm, settings_snapshot=settings_snapshot)

            mock_handler_class.assert_called_once()

    def test_handler_type_from_settings_snapshot_dict_value(self):
        """Test handler type from settings snapshot with dict value."""
        mock_llm = Mock()
        settings_snapshot = {"citation.handler_type": {"value": "precision"}}

        with patch(
            "local_deep_research.citation_handlers.precision_extraction_handler.PrecisionExtractionHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            CitationHandler(mock_llm, settings_snapshot=settings_snapshot)

            mock_handler_class.assert_called_once()

    def test_handler_type_case_insensitive(self):
        """Test handler type is case insensitive."""
        mock_llm = Mock()

        with patch(
            "local_deep_research.citation_handlers.forced_answer_citation_handler.ForcedAnswerCitationHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            CitationHandler(mock_llm, handler_type="FORCED")

            mock_handler_class.assert_called_once()


class TestCitationHandlerMethods:
    """Tests for CitationHandler method delegation."""

    def test_analyze_initial_delegation(self):
        """Test analyze_initial delegates to handler."""
        mock_llm = Mock()

        with patch(
            "local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler.analyze_initial.return_value = {"result": "test"}
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            handler = CitationHandler(mock_llm)
            result = handler.analyze_initial("test query", [])

            mock_handler.analyze_initial.assert_called_once_with(
                "test query", []
            )
            assert result == {"result": "test"}

    def test_analyze_followup_delegation(self):
        """Test analyze_followup delegates to handler."""
        mock_llm = Mock()

        with patch(
            "local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler.analyze_followup.return_value = {"result": "followup"}
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            handler = CitationHandler(mock_llm)
            result = handler.analyze_followup(
                "test question", [], "previous knowledge", 5
            )

            mock_handler.analyze_followup.assert_called_once_with(
                "test question", [], "previous knowledge", 5
            )
            assert result == {"result": "followup"}

    def test_backward_compatibility_methods_exposed(self):
        """Test backward compatibility methods are exposed."""
        mock_llm = Mock()

        with patch(
            "local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
        ) as mock_handler_class:
            mock_create_docs = Mock()
            mock_format_sources = Mock()

            mock_handler = Mock()
            mock_handler._create_documents = mock_create_docs
            mock_handler._format_sources = mock_format_sources
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            handler = CitationHandler(mock_llm)

            assert handler._create_documents == mock_create_docs
            assert handler._format_sources == mock_format_sources


class TestCitationHandlerSettings:
    """Tests for CitationHandler settings handling."""

    def test_empty_settings_snapshot(self):
        """Test with empty settings snapshot."""
        mock_llm = Mock()

        with patch(
            "local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            CitationHandler(mock_llm, settings_snapshot={})

            # Should use standard handler as default
            mock_handler_class.assert_called_once()

    def test_settings_passed_to_handler(self):
        """Test settings are passed to underlying handler."""
        mock_llm = Mock()
        settings_snapshot = {"some_setting": "value"}

        with patch(
            "local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            CitationHandler(mock_llm, settings_snapshot=settings_snapshot)

            call_kwargs = mock_handler_class.call_args[1]
            assert call_kwargs["settings_snapshot"] == settings_snapshot

    def test_llm_passed_to_handler(self):
        """Test LLM is passed to underlying handler."""
        mock_llm = Mock()

        with patch(
            "local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
        ) as mock_handler_class:
            mock_handler = Mock()
            mock_handler._create_documents = Mock()
            mock_handler._format_sources = Mock()
            mock_handler_class.return_value = mock_handler

            from local_deep_research.citation_handler import CitationHandler

            CitationHandler(mock_llm)

            call_args = mock_handler_class.call_args[0]
            assert call_args[0] == mock_llm
