"""Test environment variable auto-generation and external variables."""

import os
from unittest.mock import patch

from local_deep_research.settings.env_settings import (
    BooleanSetting,
    StringSetting,
    IntegerSetting,
    PathSetting,
    SecretSetting,
    EnumSetting,
)


class TestEnvVarAutoGeneration:
    """Test that environment variable names are auto-generated correctly."""

    def test_simple_key_generation(self):
        """Test basic key to env var conversion."""
        test_cases = [
            ("testing.test_mode", "LDR_TESTING_TEST_MODE"),
            ("bootstrap.data_dir", "LDR_BOOTSTRAP_DATA_DIR"),
            ("db_config.cache_size", "LDR_DB_CONFIG_CACHE_SIZE"),
            ("app.debug", "LDR_APP_DEBUG"),
            ("search.max_results", "LDR_SEARCH_MAX_RESULTS"),
        ]

        for key, expected_env_var in test_cases:
            setting = StringSetting(key, "Test description")
            assert setting.env_var == expected_env_var, f"Failed for key: {key}"

    def test_all_setting_types_generate_correctly(self):
        """Test that all setting types auto-generate env vars."""
        settings = [
            BooleanSetting("test.bool", "Bool setting"),
            StringSetting("test.string", "String setting"),
            IntegerSetting("test.int", "Int setting"),
            PathSetting("test.path", "Path setting"),
            SecretSetting("test.secret", "Secret setting"),
            EnumSetting("test.enum", "Enum setting", allowed_values={"A", "B"}),
        ]

        for setting in settings:
            assert setting.env_var.startswith("LDR_TEST_")
            assert (
                setting.env_var
                == f"LDR_TEST_{setting.key.split('.')[-1].upper()}"
            )

    def test_no_duplicate_env_vars_in_registry(self):
        """Test that all registered settings have unique env vars."""
        from local_deep_research.settings.env_registry import registry

        all_env_vars = []
        for key in registry.list_all_settings():
            env_var = registry.get_env_var(key)
            if env_var:
                all_env_vars.append(env_var)

        # Check for duplicates
        assert len(all_env_vars) == len(set(all_env_vars)), (
            "Duplicate env vars found!"
        )

    def test_env_var_reading(self):
        """Test that settings correctly read from environment."""
        test_env_var = "LDR_TEST_SETTING"
        test_value = "test_value_123"

        with patch.dict(os.environ, {test_env_var: test_value}):
            setting = StringSetting("test.setting", "Test")
            assert setting.get_value() == test_value

    def test_boolean_conversion(self):
        """Test boolean environment variable conversion."""
        setting = BooleanSetting("test.flag", "Test flag")

        test_cases = [
            ("true", True),
            ("True", True),
            ("TRUE", True),
            ("1", True),
            ("yes", True),
            ("false", False),
            ("False", False),
            ("0", False),
            ("no", False),
            ("", False),
        ]

        for env_value, expected in test_cases:
            with patch.dict(os.environ, {"LDR_TEST_FLAG": env_value}):
                assert setting.get_value() == expected, (
                    f"Failed for value: {env_value}"
                )


class TestExternalEnvVars:
    """Test external environment variables (CI, GITHUB_ACTIONS, etc.)."""

    def test_external_vars_are_booleans(self):
        """Test that external vars are properly converted to booleans."""
        from local_deep_research.settings.env_definitions.testing import (
            CI,
            GITHUB_ACTIONS,
            TESTING,
        )

        # They should be booleans
        assert isinstance(CI, bool)
        assert isinstance(GITHUB_ACTIONS, bool)
        assert isinstance(TESTING, bool)

    def test_external_vars_respond_to_environment(self):
        """Test that external vars read from environment correctly."""
        # We need to reimport the module after changing env vars
        with patch.dict(
            os.environ, {"CI": "true", "GITHUB_ACTIONS": "1", "TESTING": "yes"}
        ):
            # Clear the module from cache and reimport
            import sys

            if (
                "local_deep_research.settings.env_definitions.testing"
                in sys.modules
            ):
                del sys.modules[
                    "local_deep_research.settings.env_definitions.testing"
                ]

            from local_deep_research.settings.env_definitions.testing import (
                CI,
                GITHUB_ACTIONS,
                TESTING,
            )

            assert CI is True
            assert GITHUB_ACTIONS is True
            assert TESTING is True

    def test_external_vars_default_to_false(self):
        """Test that external vars default to False when not set."""
        with patch.dict(os.environ, {}, clear=True):
            # Clear and reimport
            import sys

            if (
                "local_deep_research.settings.env_definitions.testing"
                in sys.modules
            ):
                del sys.modules[
                    "local_deep_research.settings.env_definitions.testing"
                ]

            from local_deep_research.settings.env_definitions.testing import (
                CI,
                GITHUB_ACTIONS,
                TESTING,
            )

            assert CI is False
            assert GITHUB_ACTIONS is False
            assert TESTING is False


class TestBackwardCompatibility:
    """Test that the refactoring maintains backward compatibility."""

    def test_expected_env_var_names(self):
        """Test that common env vars still map to expected names."""
        from local_deep_research.settings.env_registry import registry

        # These are the env vars that existing code might depend on
        expected_mappings = [
            ("testing.test_mode", "LDR_TESTING_TEST_MODE"),
            ("bootstrap.encryption_key", "LDR_BOOTSTRAP_ENCRYPTION_KEY"),
            ("bootstrap.database_url", "LDR_BOOTSTRAP_DATABASE_URL"),
            ("bootstrap.data_dir", "LDR_BOOTSTRAP_DATA_DIR"),
            ("db_config.cache_size_mb", "LDR_DB_CONFIG_CACHE_SIZE_MB"),
        ]

        for key, expected_env_var in expected_mappings:
            actual = registry.get_env_var(key)
            assert actual == expected_env_var, (
                f"Backward compatibility broken for {key}"
            )
