"""
Tests for web/services/settings_service.py

Tests cover:
- set_setting function
- get_all_settings function
- create_or_update_setting function
- validate_setting function
"""

from unittest.mock import Mock, patch


class TestSetSetting:
    """Tests for set_setting function."""

    def test_set_setting_success(self):
        """Test successful setting update."""
        from local_deep_research.web.services.settings_service import (
            set_setting,
        )

        mock_manager = Mock()
        mock_manager.set_setting.return_value = True

        with patch(
            "local_deep_research.web.services.settings_service.get_settings_manager",
            return_value=mock_manager,
        ):
            result = set_setting("test.key", "test_value")

            assert result is True
            mock_manager.set_setting.assert_called_once_with(
                "test.key", "test_value", True
            )

    def test_set_setting_failure(self):
        """Test failed setting update."""
        from local_deep_research.web.services.settings_service import (
            set_setting,
        )

        mock_manager = Mock()
        mock_manager.set_setting.return_value = False

        with patch(
            "local_deep_research.web.services.settings_service.get_settings_manager",
            return_value=mock_manager,
        ):
            result = set_setting("test.key", "bad_value")

            assert result is False

    def test_set_setting_with_db_session(self):
        """Test setting with custom db session."""
        from local_deep_research.web.services.settings_service import (
            set_setting,
        )

        mock_manager = Mock()
        mock_manager.set_setting.return_value = True
        mock_session = Mock()

        with patch(
            "local_deep_research.web.services.settings_service.get_settings_manager",
            return_value=mock_manager,
        ) as mock_get_manager:
            result = set_setting("key", "value", db_session=mock_session)

            mock_get_manager.assert_called_once_with(mock_session)
            assert result is True

    def test_set_setting_no_commit(self):
        """Test setting without commit."""
        from local_deep_research.web.services.settings_service import (
            set_setting,
        )

        mock_manager = Mock()
        mock_manager.set_setting.return_value = True

        with patch(
            "local_deep_research.web.services.settings_service.get_settings_manager",
            return_value=mock_manager,
        ):
            set_setting("key", "value", commit=False)

            mock_manager.set_setting.assert_called_once_with(
                "key", "value", False
            )


class TestGetAllSettings:
    """Tests for get_all_settings function."""

    def test_get_all_settings_success(self):
        """Test getting all settings."""
        from local_deep_research.web.services.settings_service import (
            get_all_settings,
        )

        mock_manager = Mock()
        mock_manager.get_all_settings.return_value = {
            "key1": "value1",
            "key2": "value2",
        }

        with patch(
            "local_deep_research.web.services.settings_service.get_settings_manager",
            return_value=mock_manager,
        ):
            result = get_all_settings()

            assert result == {"key1": "value1", "key2": "value2"}
            mock_manager.get_all_settings.assert_called_once()

    def test_get_all_settings_empty(self):
        """Test getting settings when none exist."""
        from local_deep_research.web.services.settings_service import (
            get_all_settings,
        )

        mock_manager = Mock()
        mock_manager.get_all_settings.return_value = {}

        with patch(
            "local_deep_research.web.services.settings_service.get_settings_manager",
            return_value=mock_manager,
        ):
            result = get_all_settings()

            assert result == {}


class TestCreateOrUpdateSetting:
    """Tests for create_or_update_setting function."""

    def test_create_or_update_with_dict(self):
        """Test creating/updating setting with dict."""
        from local_deep_research.web.services.settings_service import (
            create_or_update_setting,
        )

        mock_manager = Mock()
        mock_setting = Mock()
        mock_manager.create_or_update_setting.return_value = mock_setting

        setting_dict = {"key": "test.key", "value": "test_value"}

        with patch(
            "local_deep_research.web.services.settings_service.get_settings_manager",
            return_value=mock_manager,
        ):
            result = create_or_update_setting(setting_dict)

            assert result == mock_setting
            mock_manager.create_or_update_setting.assert_called_once_with(
                setting_dict, True
            )

    def test_create_or_update_with_setting_object(self):
        """Test creating/updating with Setting object."""
        from local_deep_research.web.services.settings_service import (
            create_or_update_setting,
        )

        mock_manager = Mock()
        mock_setting_input = Mock()
        mock_setting_output = Mock()
        mock_manager.create_or_update_setting.return_value = mock_setting_output

        with patch(
            "local_deep_research.web.services.settings_service.get_settings_manager",
            return_value=mock_manager,
        ):
            create_or_update_setting(mock_setting_input, commit=False)

            mock_manager.create_or_update_setting.assert_called_once_with(
                mock_setting_input, False
            )

    def test_create_or_update_returns_none_on_failure(self):
        """Test that None is returned on failure."""
        from local_deep_research.web.services.settings_service import (
            create_or_update_setting,
        )

        mock_manager = Mock()
        mock_manager.create_or_update_setting.return_value = None

        with patch(
            "local_deep_research.web.services.settings_service.get_settings_manager",
            return_value=mock_manager,
        ):
            result = create_or_update_setting({"key": "test"})

            assert result is None


class TestValidateSetting:
    """Tests for validate_setting function."""

    def test_validate_setting_calls_routes_validate(self):
        """Test that validate_setting calls routes validate."""
        mock_setting = Mock()
        mock_value = "test_value"

        with patch(
            "local_deep_research.web.routes.settings_routes.validate_setting",
            return_value=(True, None),
        ):
            from local_deep_research.web.services.settings_service import (
                validate_setting,
            )

            result = validate_setting(mock_setting, mock_value)

            assert result == (True, None)

    def test_validate_setting_invalid(self):
        """Test validation failure."""
        mock_setting = Mock()

        with patch(
            "local_deep_research.web.routes.settings_routes.validate_setting",
            return_value=(False, "Value out of range"),
        ):
            from local_deep_research.web.services.settings_service import (
                validate_setting,
            )

            result = validate_setting(mock_setting, -1)

            assert result[0] is False
            assert result[1] is not None
