"""
Tests for Iterative Reasoning Strategy

Phase 18: Advanced Search Strategies - Iterative Reasoning Tests
Tests reasoning iterations, knowledge building, and convergence.
"""

from unittest.mock import patch, MagicMock


class TestIterativeReasoning:
    """Tests for iterative reasoning functionality"""

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_initial_hypothesis_generation(self, mock_strategy_cls):
        """Test initial hypothesis is generated"""
        mock_strategy = MagicMock()
        mock_strategy._generate_initial_hypothesis.return_value = {
            "hypothesis": "Initial answer hypothesis",
            "confidence": 0.3,
        }

        hypothesis = mock_strategy._generate_initial_hypothesis("What is X?")

        assert "hypothesis" in hypothesis
        assert hypothesis["confidence"] < 0.5

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_hypothesis_refinement_iteration(self, mock_strategy_cls):
        """Test hypothesis is refined through iteration"""
        mock_strategy = MagicMock()
        mock_strategy._refine_hypothesis.return_value = {
            "hypothesis": "Refined answer",
            "confidence": 0.7,
            "iteration": 3,
        }

        refined = mock_strategy._refine_hypothesis(
            current_hypothesis={"hypothesis": "Initial", "confidence": 0.3},
            new_evidence=[{"text": "Supporting evidence"}],
        )

        assert refined["confidence"] > 0.3

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_evidence_integration_per_iteration(self, mock_strategy_cls):
        """Test evidence is integrated each iteration"""
        mock_strategy = MagicMock()
        mock_strategy._integrate_evidence.return_value = {
            "key_facts": ["Fact 1", "Fact 2"],
            "uncertainties_resolved": 1,
        }

        integration = mock_strategy._integrate_evidence(
            knowledge_state={"key_facts": []},
            new_evidence=[{"text": "New fact"}],
        )

        assert len(integration["key_facts"]) > 0

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_convergence_detection(self, mock_strategy_cls):
        """Test convergence is detected"""
        mock_strategy = MagicMock()
        mock_strategy._has_converged.return_value = True

        converged = mock_strategy._has_converged(
            {
                "confidence": 0.95,
                "key_facts": ["fact1", "fact2", "fact3"],
                "uncertainties": [],
            }
        )

        assert converged is True

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_divergence_handling(self, mock_strategy_cls):
        """Test divergence is handled"""
        mock_strategy = MagicMock()
        mock_strategy._handle_divergence.return_value = {
            "action": "broaden_search",
            "new_constraints": [],
        }

        handling = mock_strategy._handle_divergence(
            {"confidence_history": [0.5, 0.4, 0.3], "trend": "decreasing"}
        )

        assert "action" in handling

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_iteration_limit_enforcement(self, mock_strategy_cls):
        """Test iteration limit is enforced"""
        mock_strategy = MagicMock()
        mock_strategy.max_iterations = 10
        mock_strategy._should_stop.return_value = True

        should_stop = mock_strategy._should_stop({"iteration": 10})

        assert should_stop is True

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_quality_improvement_tracking(self, mock_strategy_cls):
        """Test quality improvement is tracked"""
        mock_strategy = MagicMock()
        mock_strategy._track_improvement.return_value = {
            "improvement_rate": 0.1,
            "iterations": [0.3, 0.5, 0.7, 0.8],
        }

        tracking = mock_strategy._track_improvement([0.3, 0.5, 0.7, 0.8])

        assert tracking["improvement_rate"] > 0

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_chain_building(self, mock_strategy_cls):
        """Test reasoning chain is built"""
        mock_strategy = MagicMock()
        mock_strategy._build_reasoning_chain.return_value = [
            {"step": 1, "reasoning": "Initial observation"},
            {"step": 2, "reasoning": "Further analysis"},
            {"step": 3, "reasoning": "Conclusion"},
        ]

        chain = mock_strategy._build_reasoning_chain(
            "query", [{"text": "evidence"}]
        )

        assert len(chain) == 3

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_step_validation(self, mock_strategy_cls):
        """Test reasoning steps are validated"""
        mock_strategy = MagicMock()
        mock_strategy._validate_reasoning_step.return_value = {
            "valid": True,
            "issues": [],
        }

        validation = mock_strategy._validate_reasoning_step(
            {"step": 1, "reasoning": "Valid reasoning"}
        )

        assert validation["valid"] is True

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_contradiction_resolution(self, mock_strategy_cls):
        """Test contradictions are resolved"""
        mock_strategy = MagicMock()
        mock_strategy._resolve_contradiction.return_value = {
            "resolution": "Claim A is correct based on newer evidence",
            "discarded": "Claim B",
        }

        resolution = mock_strategy._resolve_contradiction("Claim A", "Claim B")

        assert "resolution" in resolution

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_gap_filling(self, mock_strategy_cls):
        """Test reasoning gaps are filled"""
        mock_strategy = MagicMock()
        mock_strategy._fill_gaps.return_value = {
            "gaps_identified": ["Gap 1"],
            "gaps_filled": ["Gap 1"],
            "remaining_gaps": [],
        }

        filling = mock_strategy._fill_gaps({"reasoning_chain": []})

        assert len(filling["remaining_gaps"]) == 0

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_depth_control(self, mock_strategy_cls):
        """Test reasoning depth is controlled"""
        mock_strategy = MagicMock()
        mock_strategy._control_depth.return_value = {
            "current_depth": 3,
            "max_depth": 5,
            "should_go_deeper": True,
        }

        control = mock_strategy._control_depth({"depth": 3})

        assert control["should_go_deeper"] is True

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_breadth_control(self, mock_strategy_cls):
        """Test reasoning breadth is controlled"""
        mock_strategy = MagicMock()
        mock_strategy._control_breadth.return_value = {
            "topics_explored": 5,
            "max_topics": 10,
            "should_explore_more": True,
        }

        control = mock_strategy._control_breadth({"topics": 5})

        assert control["should_explore_more"] is True

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_priority_ordering(self, mock_strategy_cls):
        """Test reasoning priorities are ordered"""
        mock_strategy = MagicMock()
        mock_strategy._prioritize_reasoning.return_value = [
            {"topic": "High priority", "score": 0.9},
            {"topic": "Medium priority", "score": 0.6},
            {"topic": "Low priority", "score": 0.3},
        ]

        priorities = mock_strategy._prioritize_reasoning(
            [
                {"topic": "Low priority"},
                {"topic": "High priority"},
                {"topic": "Medium priority"},
            ]
        )

        assert priorities[0]["score"] > priorities[1]["score"]

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_pruning_strategy(self, mock_strategy_cls):
        """Test irrelevant reasoning is pruned"""
        mock_strategy = MagicMock()
        mock_strategy._prune_reasoning.return_value = {
            "kept": 5,
            "pruned": 3,
            "remaining": ["r1", "r2", "r3", "r4", "r5"],
        }

        pruning = mock_strategy._prune_reasoning(
            [{"relevance": 0.9}, {"relevance": 0.8}, {"relevance": 0.1}]
        )

        assert pruning["kept"] > pruning["pruned"]

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_multi_path_reasoning(self, mock_strategy_cls):
        """Test multiple reasoning paths are explored"""
        mock_strategy = MagicMock()
        mock_strategy._explore_paths.return_value = {
            "paths": [
                {"path": "A -> B -> C", "confidence": 0.8},
                {"path": "A -> D -> C", "confidence": 0.7},
            ]
        }

        paths = mock_strategy._explore_paths("query")

        assert len(paths["paths"]) == 2

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_merge_paths(self, mock_strategy_cls):
        """Test reasoning paths are merged"""
        mock_strategy = MagicMock()
        mock_strategy._merge_paths.return_value = {
            "merged_conclusion": "Combined conclusion",
            "paths_merged": 2,
        }

        merged = mock_strategy._merge_paths(
            [{"conclusion": "C1"}, {"conclusion": "C2"}]
        )

        assert "merged_conclusion" in merged

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_confidence_propagation(self, mock_strategy_cls):
        """Test confidence propagates through reasoning"""
        mock_strategy = MagicMock()
        mock_strategy._propagate_confidence.return_value = {
            "initial_confidence": 0.9,
            "propagated_confidence": 0.8,
            "decay_applied": True,
        }

        propagation = mock_strategy._propagate_confidence(
            {"confidence": 0.9}, steps=3
        )

        assert (
            propagation["propagated_confidence"]
            < propagation["initial_confidence"]
        )

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_uncertainty_handling(self, mock_strategy_cls):
        """Test uncertainty is handled in reasoning"""
        mock_strategy = MagicMock()
        mock_strategy._handle_uncertainty.return_value = {
            "uncertainties": ["U1", "U2"],
            "mitigation": "Additional search needed",
        }

        handling = mock_strategy._handle_uncertainty(["U1", "U2"])

        assert "mitigation" in handling

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_assumption_tracking(self, mock_strategy_cls):
        """Test assumptions are tracked"""
        mock_strategy = MagicMock()
        mock_strategy._track_assumptions.return_value = {
            "assumptions": ["A1", "A2"],
            "validated": ["A1"],
            "unvalidated": ["A2"],
        }

        tracking = mock_strategy._track_assumptions(["A1", "A2"])

        assert len(tracking["assumptions"]) == 2

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_conclusion_extraction(self, mock_strategy_cls):
        """Test conclusions are extracted"""
        mock_strategy = MagicMock()
        mock_strategy._extract_conclusion.return_value = {
            "conclusion": "Final answer",
            "confidence": 0.85,
            "supporting_facts": 5,
        }

        conclusion = mock_strategy._extract_conclusion(
            {"reasoning_chain": [], "key_facts": []}
        )

        assert "conclusion" in conclusion

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_supporting_evidence(self, mock_strategy_cls):
        """Test supporting evidence is collected"""
        mock_strategy = MagicMock()
        mock_strategy._collect_supporting_evidence.return_value = [
            {"text": "Evidence 1", "relevance": 0.9},
            {"text": "Evidence 2", "relevance": 0.8},
        ]

        evidence = mock_strategy._collect_supporting_evidence("conclusion")

        assert len(evidence) == 2

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_counterargument_handling(self, mock_strategy_cls):
        """Test counterarguments are handled"""
        mock_strategy = MagicMock()
        mock_strategy._handle_counterarguments.return_value = {
            "counterarguments": ["CA1"],
            "refutations": ["Refutation of CA1"],
            "unaddressed": [],
        }

        handling = mock_strategy._handle_counterarguments(["CA1"])

        assert len(handling["unaddressed"]) == 0

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_synthesis_generation(self, mock_strategy_cls):
        """Test synthesis is generated"""
        mock_strategy = MagicMock()
        mock_strategy._generate_synthesis.return_value = {
            "synthesis": "Comprehensive answer",
            "components_used": 5,
        }

        synthesis = mock_strategy._generate_synthesis(
            {"key_facts": [], "reasoning_chain": []}
        )

        assert "synthesis" in synthesis

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_summary_creation(self, mock_strategy_cls):
        """Test summary is created"""
        mock_strategy = MagicMock()
        mock_strategy._create_summary.return_value = {
            "summary": "Brief summary of findings",
            "word_count": 50,
        }

        summary = mock_strategy._create_summary(
            {"full_answer": "Long detailed answer..."}
        )

        assert summary["word_count"] < 100

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_quality_assessment(self, mock_strategy_cls):
        """Test reasoning quality is assessed"""
        mock_strategy = MagicMock()
        mock_strategy._assess_reasoning_quality.return_value = {
            "quality_score": 0.85,
            "strengths": ["Well-supported"],
            "weaknesses": [],
        }

        assessment = mock_strategy._assess_reasoning_quality(
            {"reasoning_chain": []}
        )

        assert assessment["quality_score"] >= 0.8

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_feedback_integration(self, mock_strategy_cls):
        """Test feedback is integrated"""
        mock_strategy = MagicMock()
        mock_strategy._integrate_feedback.return_value = {
            "adjustments_made": True,
            "new_confidence": 0.75,
        }

        integration = mock_strategy._integrate_feedback(
            {"rating": 4, "comment": "Good but needs more depth"}
        )

        assert integration["adjustments_made"] is True

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_learning_from_outcome(self, mock_strategy_cls):
        """Test learning from outcomes"""
        mock_strategy = MagicMock()
        mock_strategy._learn_from_outcome.return_value = {
            "patterns_learned": ["Pattern 1"],
            "success_rate_updated": True,
        }

        learning = mock_strategy._learn_from_outcome(
            {"success": True, "user_rating": 5}
        )

        assert len(learning["patterns_learned"]) > 0

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_context_management(self, mock_strategy_cls):
        """Test context is managed"""
        mock_strategy = MagicMock()
        mock_strategy._manage_context.return_value = {
            "context_size": 2000,
            "truncated": False,
        }

        management = mock_strategy._manage_context(
            {"accumulated_context": "..." * 500}
        )

        assert not management["truncated"]

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_reasoning_resource_optimization(self, mock_strategy_cls):
        """Test resources are optimized"""
        mock_strategy = MagicMock()
        mock_strategy._optimize_resources.return_value = {
            "llm_calls_reduced": 2,
            "search_calls_optimized": True,
        }

        optimization = mock_strategy._optimize_resources(
            {"budget_remaining": 0.5}
        )

        assert optimization["search_calls_optimized"] is True


class TestKnowledgeState:
    """Tests for KnowledgeState dataclass"""

    def test_knowledge_state_creation(self):
        """Test KnowledgeState can be created"""
        from dataclasses import dataclass

        @dataclass
        class MockKnowledgeState:
            original_query: str
            key_facts: list
            uncertainties: list
            search_history: list
            candidate_answers: list
            confidence: float
            iteration: int

        state = MockKnowledgeState(
            original_query="test query",
            key_facts=["fact1"],
            uncertainties=["uncertainty1"],
            search_history=[],
            candidate_answers=[],
            confidence=0.5,
            iteration=1,
        )

        assert state.original_query == "test query"
        assert state.confidence == 0.5

    def test_knowledge_state_to_string(self):
        """Test KnowledgeState string representation"""
        from dataclasses import dataclass

        @dataclass
        class MockKnowledgeState:
            original_query: str
            key_facts: list

            def to_string(self):
                return f"Query: {self.original_query}, Facts: {self.key_facts}"

        state = MockKnowledgeState(
            original_query="test", key_facts=["fact1", "fact2"]
        )

        string_repr = state.to_string()

        assert "test" in string_repr
        assert "fact1" in string_repr


class TestSearchDecision:
    """Tests for search decision logic"""

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_decide_next_search(self, mock_strategy_cls):
        """Test next search decision"""
        mock_strategy = MagicMock()
        mock_strategy._decide_next_search.return_value = {
            "search_query": "refined query",
            "strategy": "targeted",
        }

        decision = mock_strategy._decide_next_search(
            {"key_facts": [], "uncertainties": ["What is X?"]}
        )

        assert "search_query" in decision

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_execute_search(self, mock_strategy_cls):
        """Test search execution"""
        mock_strategy = MagicMock()
        mock_strategy._execute_search.return_value = {
            "results": [{"title": "Result 1"}],
            "count": 1,
        }

        results = mock_strategy._execute_search("search query")

        assert results["count"] == 1

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_update_knowledge(self, mock_strategy_cls):
        """Test knowledge update"""
        mock_strategy = MagicMock()
        mock_strategy._update_knowledge.return_value = {
            "key_facts": ["new_fact"],
            "uncertainties_resolved": 1,
        }

        update = mock_strategy._update_knowledge([{"text": "New information"}])

        assert len(update["key_facts"]) > 0

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_assess_answer(self, mock_strategy_cls):
        """Test answer assessment"""
        mock_strategy = MagicMock()
        mock_strategy._assess_answer.return_value = {
            "confidence": 0.85,
            "complete": True,
        }

        assessment = mock_strategy._assess_answer(
            {"candidate_answers": [{"answer": "test", "confidence": 0.85}]}
        )

        assert assessment["confidence"] >= 0.8

    @patch(
        "local_deep_research.advanced_search_system.strategies.iterative_reasoning_strategy.IterativeReasoningStrategy"
    )
    def test_synthesize_final_answer(self, mock_strategy_cls):
        """Test final answer synthesis"""
        mock_strategy = MagicMock()
        mock_strategy._synthesize_final_answer.return_value = {
            "answer": "Final synthesized answer",
            "sources": ["source1", "source2"],
        }

        answer = mock_strategy._synthesize_final_answer(
            {
                "key_facts": ["fact1"],
                "candidate_answers": [{"answer": "candidate"}],
            }
        )

        assert "answer" in answer
