"""
Tests for SimpleQAEvaluator class.

Tests the SimpleQA benchmark evaluator implementation.
"""

import tempfile
from pathlib import Path
from unittest.mock import patch


from local_deep_research.benchmarks.evaluators.simpleqa import SimpleQAEvaluator
from local_deep_research.benchmarks.evaluators.base import (
    BaseBenchmarkEvaluator,
)


class TestSimpleQAEvaluatorInit:
    """Test initialization of SimpleQAEvaluator."""

    def test_init_sets_name(self):
        """Test that initialization sets the benchmark name to 'simpleqa'."""
        evaluator = SimpleQAEvaluator()
        assert evaluator.name == "simpleqa"

    def test_inherits_from_base(self):
        """Test that SimpleQAEvaluator inherits from BaseBenchmarkEvaluator."""
        evaluator = SimpleQAEvaluator()
        assert isinstance(evaluator, BaseBenchmarkEvaluator)

    def test_get_name_returns_simpleqa(self):
        """Test that get_name returns 'simpleqa'."""
        evaluator = SimpleQAEvaluator()
        assert evaluator.get_name() == "simpleqa"


class TestSimpleQAEvaluateWithRunner:
    """Test evaluate method with legacy runner."""

    @patch(
        "local_deep_research.benchmarks.evaluators.simpleqa.run_simpleqa_benchmark"
    )
    def test_evaluate_calls_runner_when_not_direct(self, mock_runner):
        """Test that evaluate calls run_simpleqa_benchmark when use_direct_dataset=False."""
        mock_runner.return_value = {
            "metrics": {"accuracy": 0.75},
            "report_path": "/tmp/report.md",
        }

        with tempfile.TemporaryDirectory() as tmpdir:
            evaluator = SimpleQAEvaluator()
            evaluator.evaluate(
                system_config={"key": "value"},
                num_examples=10,
                output_dir=tmpdir,
                use_direct_dataset=False,
            )

            mock_runner.assert_called_once()
            call_kwargs = mock_runner.call_args[1]
            assert call_kwargs["num_examples"] == 10
            assert call_kwargs["run_evaluation"] is True

    @patch(
        "local_deep_research.benchmarks.evaluators.simpleqa.run_simpleqa_benchmark"
    )
    def test_evaluate_returns_accuracy_from_runner(self, mock_runner):
        """Test that evaluate returns accuracy from runner results."""
        mock_runner.return_value = {
            "metrics": {"accuracy": 0.85},
            "report_path": "/tmp/report.md",
        }

        with tempfile.TemporaryDirectory() as tmpdir:
            evaluator = SimpleQAEvaluator()
            result = evaluator.evaluate(
                system_config={},
                num_examples=5,
                output_dir=tmpdir,
                use_direct_dataset=False,
            )

            assert result["accuracy"] == 0.85
            assert result["quality_score"] == 0.85

    @patch(
        "local_deep_research.benchmarks.evaluators.simpleqa.run_simpleqa_benchmark"
    )
    def test_evaluate_returns_benchmark_type(self, mock_runner):
        """Test that evaluate returns correct benchmark_type."""
        mock_runner.return_value = {
            "metrics": {"accuracy": 0.5},
            "report_path": "/tmp/report.md",
        }

        with tempfile.TemporaryDirectory() as tmpdir:
            evaluator = SimpleQAEvaluator()
            result = evaluator.evaluate(
                system_config={},
                num_examples=5,
                output_dir=tmpdir,
                use_direct_dataset=False,
            )

            assert result["benchmark_type"] == "simpleqa"

    @patch(
        "local_deep_research.benchmarks.evaluators.simpleqa.run_simpleqa_benchmark"
    )
    def test_evaluate_includes_raw_results(self, mock_runner):
        """Test that evaluate includes raw_results from runner."""
        raw_data = {
            "metrics": {"accuracy": 0.6},
            "report_path": "/tmp/report.md",
            "extra_data": "test",
        }
        mock_runner.return_value = raw_data

        with tempfile.TemporaryDirectory() as tmpdir:
            evaluator = SimpleQAEvaluator()
            result = evaluator.evaluate(
                system_config={},
                num_examples=5,
                output_dir=tmpdir,
                use_direct_dataset=False,
            )

            assert result["raw_results"] == raw_data

    @patch(
        "local_deep_research.benchmarks.evaluators.simpleqa.run_simpleqa_benchmark"
    )
    def test_evaluate_passes_search_config(self, mock_runner):
        """Test that evaluate passes search_config to runner."""
        mock_runner.return_value = {
            "metrics": {"accuracy": 0.5},
            "report_path": None,
        }

        config = {"iterations": 5, "search_tool": "google"}

        with tempfile.TemporaryDirectory() as tmpdir:
            evaluator = SimpleQAEvaluator()
            evaluator.evaluate(
                system_config=config,
                num_examples=10,
                output_dir=tmpdir,
                use_direct_dataset=False,
            )

            call_kwargs = mock_runner.call_args[1]
            assert call_kwargs["search_config"] == config


class TestSimpleQAEvaluateWithDirectDataset:
    """Test evaluate method with direct dataset class."""

    @patch.object(SimpleQAEvaluator, "_run_with_dataset_class")
    def test_evaluate_uses_direct_dataset_by_default(self, mock_method):
        """Test that evaluate uses direct dataset by default."""
        mock_method.return_value = {
            "status": "complete",
            "metrics": {"accuracy": 0.8},
            "accuracy": 0.8,
        }

        with tempfile.TemporaryDirectory() as tmpdir:
            evaluator = SimpleQAEvaluator()
            evaluator.evaluate(
                system_config={},
                num_examples=5,
                output_dir=tmpdir,
            )

            mock_method.assert_called_once()

    @patch.object(SimpleQAEvaluator, "_run_with_dataset_class")
    def test_evaluate_passes_params_to_direct_method(self, mock_method):
        """Test that evaluate passes correct params to direct method."""
        mock_method.return_value = {
            "status": "complete",
            "metrics": {"accuracy": 0.7},
            "accuracy": 0.7,
        }

        config = {"seed": 123, "iterations": 3}

        with tempfile.TemporaryDirectory() as tmpdir:
            evaluator = SimpleQAEvaluator()
            evaluator.evaluate(
                system_config=config,
                num_examples=15,
                output_dir=tmpdir,
                use_direct_dataset=True,
            )

            call_kwargs = mock_method.call_args[1]
            assert call_kwargs["system_config"] == config
            assert call_kwargs["num_examples"] == 15


class TestSimpleQAEvaluateErrors:
    """Test error handling in evaluate method."""

    @patch(
        "local_deep_research.benchmarks.evaluators.simpleqa.run_simpleqa_benchmark"
    )
    def test_evaluate_handles_runner_exception(self, mock_runner):
        """Test that evaluate handles exceptions from runner."""
        mock_runner.side_effect = RuntimeError("Benchmark failed")

        with tempfile.TemporaryDirectory() as tmpdir:
            evaluator = SimpleQAEvaluator()
            result = evaluator.evaluate(
                system_config={},
                num_examples=5,
                output_dir=tmpdir,
                use_direct_dataset=False,
            )

            assert result["benchmark_type"] == "simpleqa"
            assert result["quality_score"] == 0.0
            assert result["accuracy"] == 0.0
            assert "error" in result
            assert "Benchmark failed" in result["error"]

    @patch(
        "local_deep_research.benchmarks.evaluators.simpleqa.run_simpleqa_benchmark"
    )
    def test_evaluate_handles_missing_metrics(self, mock_runner):
        """Test that evaluate handles missing metrics in results."""
        mock_runner.return_value = {}  # No metrics key

        with tempfile.TemporaryDirectory() as tmpdir:
            evaluator = SimpleQAEvaluator()
            result = evaluator.evaluate(
                system_config={},
                num_examples=5,
                output_dir=tmpdir,
                use_direct_dataset=False,
            )

            assert result["accuracy"] == 0.0
            assert result["quality_score"] == 0.0

    @patch(
        "local_deep_research.benchmarks.evaluators.simpleqa.run_simpleqa_benchmark"
    )
    def test_evaluate_handles_missing_accuracy(self, mock_runner):
        """Test that evaluate handles missing accuracy in metrics."""
        mock_runner.return_value = {"metrics": {}}  # No accuracy key

        with tempfile.TemporaryDirectory() as tmpdir:
            evaluator = SimpleQAEvaluator()
            result = evaluator.evaluate(
                system_config={},
                num_examples=5,
                output_dir=tmpdir,
                use_direct_dataset=False,
            )

            assert result["accuracy"] == 0.0
            assert result["quality_score"] == 0.0


class TestSimpleQACreateSubdirectory:
    """Test subdirectory creation."""

    @patch(
        "local_deep_research.benchmarks.evaluators.simpleqa.run_simpleqa_benchmark"
    )
    def test_evaluate_creates_subdirectory(self, mock_runner):
        """Test that evaluate creates benchmark-specific subdirectory."""
        mock_runner.return_value = {
            "metrics": {"accuracy": 0.5},
            "report_path": None,
        }

        with tempfile.TemporaryDirectory() as tmpdir:
            evaluator = SimpleQAEvaluator()
            evaluator.evaluate(
                system_config={},
                num_examples=5,
                output_dir=tmpdir,
                use_direct_dataset=False,
            )

            # Check that subdirectory was created
            expected_subdir = Path(tmpdir) / "simpleqa"
            assert expected_subdir.exists()


class TestSimpleQAQualityScore:
    """Test quality_score mapping."""

    @patch(
        "local_deep_research.benchmarks.evaluators.simpleqa.run_simpleqa_benchmark"
    )
    def test_quality_score_equals_accuracy(self, mock_runner):
        """Test that quality_score is mapped directly from accuracy."""
        mock_runner.return_value = {
            "metrics": {"accuracy": 0.923},
            "report_path": None,
        }

        with tempfile.TemporaryDirectory() as tmpdir:
            evaluator = SimpleQAEvaluator()
            result = evaluator.evaluate(
                system_config={},
                num_examples=5,
                output_dir=tmpdir,
                use_direct_dataset=False,
            )

            assert result["quality_score"] == result["accuracy"]
            assert result["quality_score"] == 0.923

    @patch(
        "local_deep_research.benchmarks.evaluators.simpleqa.run_simpleqa_benchmark"
    )
    def test_quality_score_zero_on_error(self, mock_runner):
        """Test that quality_score is 0 on error."""
        mock_runner.side_effect = Exception("Test error")

        with tempfile.TemporaryDirectory() as tmpdir:
            evaluator = SimpleQAEvaluator()
            result = evaluator.evaluate(
                system_config={},
                num_examples=5,
                output_dir=tmpdir,
                use_direct_dataset=False,
            )

            assert result["quality_score"] == 0.0
