"""High-value pure logic tests for search_system_factory.py.

Tests AVAILABLE_STRATEGIES, get_available_strategies(), and _get_setting()
without importing any strategy classes.
"""

import pytest

from local_deep_research.search_system_factory import (
    ALL_STRATEGIES,
    AVAILABLE_STRATEGIES,
    _get_setting,
    get_available_strategies,
)


class TestAvailableStrategiesList:
    """Tests for the AVAILABLE_STRATEGIES module-level constant."""

    def test_is_a_list(self):
        assert isinstance(AVAILABLE_STRATEGIES, list)

    def test_expected_count(self):
        assert len(AVAILABLE_STRATEGIES) == 5

    def test_all_entries_are_dicts(self):
        for entry in AVAILABLE_STRATEGIES:
            assert isinstance(entry, dict)

    def test_all_entries_have_name_key(self):
        for entry in AVAILABLE_STRATEGIES:
            assert "name" in entry

    def test_all_entries_have_description_key(self):
        for entry in AVAILABLE_STRATEGIES:
            assert "description" in entry

    def test_all_names_are_nonempty_strings(self):
        for entry in AVAILABLE_STRATEGIES:
            assert isinstance(entry["name"], str)
            assert len(entry["name"]) > 0

    def test_all_descriptions_are_nonempty_strings(self):
        for entry in AVAILABLE_STRATEGIES:
            assert isinstance(entry["description"], str)
            assert len(entry["description"]) > 0

    @pytest.mark.parametrize(
        "strategy_name",
        [
            "source-based",
            "focused-iteration",
            "focused-iteration-standard",
            "mcp",
            "langgraph-agent",
        ],
    )
    def test_contains_known_strategy(self, strategy_name):
        names = [entry["name"] for entry in AVAILABLE_STRATEGIES]
        assert strategy_name in names

    def test_no_duplicate_names(self):
        names = [entry["name"] for entry in AVAILABLE_STRATEGIES]
        assert len(names) == len(set(names))

    def test_entries_have_only_expected_keys(self):
        for entry in AVAILABLE_STRATEGIES:
            assert set(entry.keys()) == {"name", "label", "description"}


class TestGetAvailableStrategies:
    """Tests for get_available_strategies() function."""

    def test_returns_a_list(self):
        result = get_available_strategies()
        assert isinstance(result, list)

    def test_returns_copy_not_original(self):
        result = get_available_strategies()
        assert result is not AVAILABLE_STRATEGIES

    def test_copy_has_same_length(self):
        result = get_available_strategies()
        assert len(result) == len(AVAILABLE_STRATEGIES)

    def test_copy_has_same_content(self):
        result = get_available_strategies()
        assert result == AVAILABLE_STRATEGIES

    def test_modifying_returned_list_does_not_affect_original(self):
        result = get_available_strategies()
        original_len = len(AVAILABLE_STRATEGIES)
        result.append({"name": "fake", "description": "fake"})
        assert len(AVAILABLE_STRATEGIES) == original_len

    def test_removing_from_returned_list_does_not_affect_original(self):
        result = get_available_strategies()
        original_len = len(AVAILABLE_STRATEGIES)
        result.pop()
        assert len(AVAILABLE_STRATEGIES) == original_len


class TestAllStrategiesList:
    """Tests for the ALL_STRATEGIES list (show_all=True)."""

    def test_all_contains_more_than_available(self):
        assert len(ALL_STRATEGIES) > len(AVAILABLE_STRATEGIES)

    def test_all_starts_with_available(self):
        """ALL_STRATEGIES should begin with AVAILABLE_STRATEGIES entries."""
        for i, entry in enumerate(AVAILABLE_STRATEGIES):
            assert ALL_STRATEGIES[i]["name"] == entry["name"]

    def test_all_entries_have_required_keys(self):
        for entry in ALL_STRATEGIES:
            assert set(entry.keys()) == {"name", "label", "description"}

    def test_no_duplicate_names_in_all(self):
        names = [entry["name"] for entry in ALL_STRATEGIES]
        assert len(names) == len(set(names))

    def test_get_available_show_all_returns_all(self):
        result = get_available_strategies(show_all=True)
        assert result == ALL_STRATEGIES

    def test_get_available_default_returns_subset(self):
        result = get_available_strategies()
        assert result == AVAILABLE_STRATEGIES
        assert len(result) < len(ALL_STRATEGIES)


class TestGetSetting:
    """Tests for _get_setting() helper function."""

    def test_returns_default_when_snapshot_is_none(self):
        assert _get_setting(None, "any_key", "default_val") == "default_val"

    def test_returns_default_when_snapshot_is_empty_dict(self):
        assert _get_setting({}, "missing_key", 42) == 42

    def test_returns_default_when_key_not_in_snapshot(self):
        snapshot = {"other_key": "other_value"}
        assert _get_setting(snapshot, "missing_key", "fallback") == "fallback"

    def test_returns_value_directly_when_not_a_dict(self):
        snapshot = {"my_key": "simple_string"}
        assert _get_setting(snapshot, "my_key", "default") == "simple_string"

    def test_returns_integer_value_directly(self):
        snapshot = {"count": 10}
        assert _get_setting(snapshot, "count", 0) == 10

    def test_returns_list_value_directly(self):
        snapshot = {"items": [1, 2, 3]}
        assert _get_setting(snapshot, "items", []) == [1, 2, 3]

    def test_extracts_value_from_dict_with_value_key(self):
        snapshot = {"my_key": {"value": "extracted"}}
        assert _get_setting(snapshot, "my_key", "default") == "extracted"

    def test_extracts_none_from_dict_with_value_key(self):
        snapshot = {"my_key": {"value": None}}
        assert _get_setting(snapshot, "my_key", "default") is None

    def test_extracts_zero_from_dict_with_value_key(self):
        snapshot = {"my_key": {"value": 0}}
        assert _get_setting(snapshot, "my_key", 99) == 0

    def test_extracts_false_from_dict_with_value_key(self):
        snapshot = {"my_key": {"value": False}}
        assert _get_setting(snapshot, "my_key", True) is False

    def test_returns_full_dict_when_no_value_key(self):
        snapshot = {"my_key": {"label": "thing", "count": 5}}
        result = _get_setting(snapshot, "my_key", "default")
        assert result == {"label": "thing", "count": 5}

    def test_returns_empty_dict_when_value_is_empty_dict(self):
        snapshot = {"my_key": {}}
        result = _get_setting(snapshot, "my_key", "default")
        assert result == {}

    def test_returns_default_with_numeric_zero_default(self):
        assert _get_setting(None, "key", 0) == 0

    def test_returns_default_with_none_default(self):
        assert _get_setting(None, "key", None) is None

    def test_returns_default_with_empty_string_default(self):
        assert _get_setting({}, "key", "") == ""

    def test_returns_default_with_false_default(self):
        assert _get_setting({}, "key", False) is False

    def test_dict_value_with_extra_keys_still_extracts_value(self):
        snapshot = {"my_key": {"value": "extracted", "metadata": "extra"}}
        assert _get_setting(snapshot, "my_key", "default") == "extracted"

    def test_nested_dict_as_extracted_value(self):
        snapshot = {"my_key": {"value": {"nested": True}}}
        assert _get_setting(snapshot, "my_key", "default") == {"nested": True}

    def test_dotted_key_is_treated_as_literal(self):
        snapshot = {"focused_iteration.adaptive_questions": {"value": 1}}
        result = _get_setting(
            snapshot, "focused_iteration.adaptive_questions", 0
        )
        assert result == 1
