"""
Test question generator classes in the advanced search system.
"""

import pytest
from loguru import logger


class TestQuestionGeneratorImports:
    """Test that question generator classes can be imported."""

    def test_standard_question_generator_import(self):
        """Test StandardQuestionGenerator import."""
        from local_deep_research.advanced_search_system.questions.standard_question import (
            StandardQuestionGenerator,
        )

        assert StandardQuestionGenerator is not None
        assert hasattr(StandardQuestionGenerator, "generate_questions")

    def test_atomic_fact_question_generator_import(self):
        """Test AtomicFactQuestionGenerator import."""
        from local_deep_research.advanced_search_system.questions.atomic_fact_question import (
            AtomicFactQuestionGenerator,
        )

        assert AtomicFactQuestionGenerator is not None
        assert hasattr(AtomicFactQuestionGenerator, "generate_questions")

    def test_browsecomp_question_generator_import(self):
        """Test BrowseCompQuestionGenerator import."""
        from local_deep_research.advanced_search_system.questions.browsecomp_question import (
            BrowseCompQuestionGenerator,
        )

        assert BrowseCompQuestionGenerator is not None

    def test_flexible_browsecomp_question_generator_import(self):
        """Test FlexibleBrowseCompQuestionGenerator import."""
        from local_deep_research.advanced_search_system.questions.flexible_browsecomp_question import (
            FlexibleBrowseCompQuestionGenerator,
        )

        assert FlexibleBrowseCompQuestionGenerator is not None

    def test_news_question_generator_import(self):
        """Test NewsQuestionGenerator import."""
        from local_deep_research.advanced_search_system.questions.news_question import (
            NewsQuestionGenerator,
        )

        assert NewsQuestionGenerator is not None


class TestStandardQuestionGenerator:
    """Test StandardQuestionGenerator functionality."""

    def test_instantiation(self, mock_llm):
        """Test that generator can be instantiated."""
        from local_deep_research.advanced_search_system.questions.standard_question import (
            StandardQuestionGenerator,
        )

        generator = StandardQuestionGenerator(mock_llm)
        assert generator is not None
        assert generator.model == mock_llm

    def test_generate_questions(self, mock_llm, sample_query):
        """Test question generation."""
        from local_deep_research.advanced_search_system.questions.standard_question import (
            StandardQuestionGenerator,
        )

        generator = StandardQuestionGenerator(mock_llm)

        questions = generator.generate_questions(
            current_knowledge="",
            query=sample_query,
            questions_per_iteration=3,
            questions_by_iteration={},
        )

        # Should return a list
        assert isinstance(questions, list)
        logger.info(f"Generated {len(questions)} questions: {questions}")


class TestAtomicFactQuestionGenerator:
    """Test AtomicFactQuestionGenerator functionality."""

    def test_instantiation(self, mock_llm):
        """Test that generator can be instantiated."""
        from local_deep_research.advanced_search_system.questions.atomic_fact_question import (
            AtomicFactQuestionGenerator,
        )

        generator = AtomicFactQuestionGenerator(mock_llm)
        assert generator is not None

    def test_generate_questions(self, mock_llm, sample_query):
        """Test atomic fact question generation."""
        from local_deep_research.advanced_search_system.questions.atomic_fact_question import (
            AtomicFactQuestionGenerator,
        )

        generator = AtomicFactQuestionGenerator(mock_llm)

        questions = generator.generate_questions(
            current_knowledge="",
            query=sample_query,
            questions_per_iteration=3,
            questions_by_iteration={},
        )

        assert isinstance(questions, list)
        logger.info(f"Generated {len(questions)} atomic fact questions")


class TestBrowseCompQuestionGenerator:
    """Test BrowseCompQuestionGenerator functionality."""

    def test_instantiation(self, mock_llm):
        """Test that generator can be instantiated."""
        from local_deep_research.advanced_search_system.questions.browsecomp_question import (
            BrowseCompQuestionGenerator,
        )

        generator = BrowseCompQuestionGenerator(mock_llm)
        assert generator is not None

    def test_generate_questions(self, mock_llm, sample_query):
        """Test browsecomp question generation."""
        from local_deep_research.advanced_search_system.questions.browsecomp_question import (
            BrowseCompQuestionGenerator,
        )

        generator = BrowseCompQuestionGenerator(mock_llm)

        try:
            questions = generator.generate_questions(
                current_knowledge="",
                query=sample_query,
                questions_per_iteration=3,
                questions_by_iteration={},
            )

            assert isinstance(questions, list)
            logger.info(f"Generated {len(questions)} browsecomp questions")

        except Exception as e:
            logger.warning(
                f"BrowseCompQuestionGenerator.generate_questions failed: {e}"
            )
            pytest.skip(f"BrowseCompQuestionGenerator has issues: {e}")


class TestNewsQuestionGenerator:
    """Test NewsQuestionGenerator functionality."""

    def test_instantiation(self, mock_llm):
        """Test that generator can be instantiated."""
        from local_deep_research.advanced_search_system.questions.news_question import (
            NewsQuestionGenerator,
        )

        generator = NewsQuestionGenerator(mock_llm)
        assert generator is not None

    def test_generate_questions(self, mock_llm):
        """Test news question generation."""
        from local_deep_research.advanced_search_system.questions.news_question import (
            NewsQuestionGenerator,
        )

        generator = NewsQuestionGenerator(mock_llm)
        query = "What are the latest developments in AI?"

        try:
            questions = generator.generate_questions(
                current_knowledge="",
                query=query,
                questions_per_iteration=3,
                questions_by_iteration={},
            )

            assert isinstance(questions, list)
            logger.info(f"Generated {len(questions)} news questions")

        except Exception as e:
            logger.warning(
                f"NewsQuestionGenerator.generate_questions failed: {e}"
            )
            pytest.skip(f"NewsQuestionGenerator has issues: {e}")


class TestQuestionGeneratorBehaviors:
    """Test specific behaviors of question generators."""

    def test_standard_generator_respects_question_count(self, mock_llm):
        """Test that generator respects questions_per_iteration limit."""
        from local_deep_research.advanced_search_system.questions.standard_question import (
            StandardQuestionGenerator,
        )

        # Mock LLM to return many questions
        mock_llm.invoke.return_value.content = (
            "Q: Question 1\n"
            "Q: Question 2\n"
            "Q: Question 3\n"
            "Q: Question 4\n"
            "Q: Question 5\n"
        )

        generator = StandardQuestionGenerator(mock_llm)
        questions = generator.generate_questions(
            current_knowledge="",
            query="Test query",
            questions_per_iteration=2,
            questions_by_iteration={},
        )

        # Should respect the limit
        assert len(questions) <= 2

    def test_standard_generator_with_existing_questions(self, mock_llm):
        """Test generator considers past questions."""
        from local_deep_research.advanced_search_system.questions.standard_question import (
            StandardQuestionGenerator,
        )

        generator = StandardQuestionGenerator(mock_llm)

        past_questions = {
            1: ["What is AI?", "How does machine learning work?"],
            2: ["What are neural networks?"],
        }

        questions = generator.generate_questions(
            current_knowledge="AI is a field of computer science.",
            query="Explain deep learning",
            questions_per_iteration=3,
            questions_by_iteration=past_questions,
        )

        # Should still return questions
        assert isinstance(questions, list)

    def test_standard_generator_sub_questions(self, mock_llm):
        """Test sub-question generation."""
        from local_deep_research.advanced_search_system.questions.standard_question import (
            StandardQuestionGenerator,
        )

        # Mock LLM to return numbered sub-questions
        mock_llm.invoke.return_value.content = (
            "1. What is the capital of France?\n"
            "2. What is the population of Paris?\n"
            "3. When was the Eiffel Tower built?\n"
        )

        generator = StandardQuestionGenerator(mock_llm)
        sub_questions = generator.generate_sub_questions(
            query="Tell me about Paris landmarks and demographics"
        )

        assert isinstance(sub_questions, list)
        assert len(sub_questions) <= 5
        logger.info(f"Generated sub-questions: {sub_questions}")

    def test_generator_handles_empty_response(self, mock_llm):
        """Test generator handles empty LLM response."""
        from local_deep_research.advanced_search_system.questions.standard_question import (
            StandardQuestionGenerator,
        )

        mock_llm.invoke.return_value.content = ""

        generator = StandardQuestionGenerator(mock_llm)
        questions = generator.generate_questions(
            current_knowledge="",
            query="Test",
            questions_per_iteration=3,
            questions_by_iteration={},
        )

        # Should return empty list, not crash
        assert isinstance(questions, list)
        assert len(questions) == 0

    def test_generator_handles_malformed_response(self, mock_llm):
        """Test generator handles malformed LLM response."""
        from local_deep_research.advanced_search_system.questions.standard_question import (
            StandardQuestionGenerator,
        )

        # Response without Q: prefix
        mock_llm.invoke.return_value.content = (
            "Here are some questions:\n"
            "- Question about topic\n"
            "- Another question\n"
        )

        generator = StandardQuestionGenerator(mock_llm)
        questions = generator.generate_questions(
            current_knowledge="",
            query="Test",
            questions_per_iteration=3,
            questions_by_iteration={},
        )

        # Should handle gracefully (may be empty due to format mismatch)
        assert isinstance(questions, list)


class TestFlexibleBrowseCompGenerator:
    """Test FlexibleBrowseCompQuestionGenerator."""

    def test_instantiation(self, mock_llm):
        """Test instantiation."""
        from local_deep_research.advanced_search_system.questions.flexible_browsecomp_question import (
            FlexibleBrowseCompQuestionGenerator,
        )

        generator = FlexibleBrowseCompQuestionGenerator(mock_llm)
        assert generator is not None
        assert generator.model == mock_llm

    def test_generate_questions(self, mock_llm, sample_query):
        """Test question generation."""
        from local_deep_research.advanced_search_system.questions.flexible_browsecomp_question import (
            FlexibleBrowseCompQuestionGenerator,
        )

        generator = FlexibleBrowseCompQuestionGenerator(mock_llm)

        try:
            questions = generator.generate_questions(
                current_knowledge="Some existing knowledge",
                query=sample_query,
                questions_per_iteration=3,
                questions_by_iteration={},
            )

            assert isinstance(questions, list)
            logger.info(f"FlexibleBrowseComp generated: {questions}")

        except Exception as e:
            logger.warning(f"FlexibleBrowseCompQuestionGenerator failed: {e}")
            pytest.skip(f"Generator has issues: {e}")
