"""
Behavioral tests for data_sanitizer module.

Tests the DataSanitizer class which removes or redacts sensitive
information from data structures.
"""


class TestSanitizeBasicDictionary:
    """Tests for sanitizing basic dictionaries."""

    def test_removes_api_key(self):
        """api_key is removed from dictionary."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"username": "user", "api_key": "secret123"}
        result = DataSanitizer.sanitize(data)
        assert "api_key" not in result
        assert result["username"] == "user"

    def test_removes_password(self):
        """password is removed from dictionary."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"username": "user", "password": "secret123"}
        result = DataSanitizer.sanitize(data)
        assert "password" not in result
        assert result["username"] == "user"

    def test_removes_secret(self):
        """secret is removed from dictionary."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"name": "service", "secret": "abc123"}
        result = DataSanitizer.sanitize(data)
        assert "secret" not in result
        assert result["name"] == "service"

    def test_removes_access_token(self):
        """access_token is removed from dictionary."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"user_id": 1, "access_token": "token123"}
        result = DataSanitizer.sanitize(data)
        assert "access_token" not in result
        assert result["user_id"] == 1

    def test_removes_refresh_token(self):
        """refresh_token is removed from dictionary."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"user_id": 1, "refresh_token": "refresh123"}
        result = DataSanitizer.sanitize(data)
        assert "refresh_token" not in result

    def test_removes_private_key(self):
        """private_key is removed from dictionary."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"key_id": "k1", "private_key": "-----BEGIN..."}
        result = DataSanitizer.sanitize(data)
        assert "private_key" not in result

    def test_removes_auth_token(self):
        """auth_token is removed from dictionary."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"session": "s1", "auth_token": "auth123"}
        result = DataSanitizer.sanitize(data)
        assert "auth_token" not in result

    def test_removes_session_token(self):
        """session_token is removed from dictionary."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"user": "u1", "session_token": "sess123"}
        result = DataSanitizer.sanitize(data)
        assert "session_token" not in result

    def test_removes_csrf_token(self):
        """csrf_token is removed from dictionary."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"form": "f1", "csrf_token": "csrf123"}
        result = DataSanitizer.sanitize(data)
        assert "csrf_token" not in result

    def test_removes_apikey_no_underscore(self):
        """apikey (without underscore) is removed."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"service": "s1", "apikey": "key123"}
        result = DataSanitizer.sanitize(data)
        assert "apikey" not in result


class TestSanitizeCaseInsensitive:
    """Tests for case-insensitive key matching."""

    def test_removes_API_KEY_uppercase(self):
        """API_KEY in uppercase is removed."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"name": "test", "API_KEY": "secret"}
        result = DataSanitizer.sanitize(data)
        assert "API_KEY" not in result

    def test_removes_Api_Key_mixed_case(self):
        """Api_Key in mixed case is removed."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"name": "test", "Api_Key": "secret"}
        result = DataSanitizer.sanitize(data)
        assert "Api_Key" not in result

    def test_removes_PASSWORD_uppercase(self):
        """PASSWORD in uppercase is removed."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"user": "u1", "PASSWORD": "secret"}
        result = DataSanitizer.sanitize(data)
        assert "PASSWORD" not in result

    def test_removes_Secret_capitalized(self):
        """Secret capitalized is removed."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"id": 1, "Secret": "mysecret"}
        result = DataSanitizer.sanitize(data)
        assert "Secret" not in result


class TestSanitizeNestedStructures:
    """Tests for nested dictionaries and lists."""

    def test_removes_key_in_nested_dict(self):
        """api_key in nested dictionary is removed."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"user": {"name": "test", "api_key": "secret"}}
        result = DataSanitizer.sanitize(data)
        assert "api_key" not in result["user"]
        assert result["user"]["name"] == "test"

    def test_removes_key_in_deeply_nested_dict(self):
        """api_key in deeply nested dictionary is removed."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"a": {"b": {"c": {"password": "secret", "value": 1}}}}
        result = DataSanitizer.sanitize(data)
        assert "password" not in result["a"]["b"]["c"]
        assert result["a"]["b"]["c"]["value"] == 1

    def test_removes_key_in_list_of_dicts(self):
        """api_key in list of dictionaries is removed."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = [{"name": "a", "api_key": "k1"}, {"name": "b", "api_key": "k2"}]
        result = DataSanitizer.sanitize(data)
        assert all("api_key" not in item for item in result)
        assert result[0]["name"] == "a"
        assert result[1]["name"] == "b"

    def test_removes_key_in_mixed_nested_structure(self):
        """api_key in mixed nested structure is removed."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {
            "users": [{"id": 1, "password": "p1"}, {"id": 2, "password": "p2"}],
            "config": {"api_key": "main_key"},
        }
        result = DataSanitizer.sanitize(data)
        assert all("password" not in user for user in result["users"])
        assert "api_key" not in result["config"]


class TestSanitizePrimitives:
    """Tests for primitive values."""

    def test_returns_string_unchanged(self):
        """String primitives are returned unchanged."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        assert DataSanitizer.sanitize("hello") == "hello"

    def test_returns_number_unchanged(self):
        """Number primitives are returned unchanged."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        assert DataSanitizer.sanitize(42) == 42
        assert DataSanitizer.sanitize(3.14) == 3.14

    def test_returns_boolean_unchanged(self):
        """Boolean primitives are returned unchanged."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        assert DataSanitizer.sanitize(True) is True
        assert DataSanitizer.sanitize(False) is False

    def test_returns_none_unchanged(self):
        """None is returned unchanged."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        assert DataSanitizer.sanitize(None) is None


class TestSanitizeCustomKeys:
    """Tests for custom sensitive key sets."""

    def test_custom_keys_are_removed(self):
        """Custom sensitive keys are removed."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"custom_secret": "value", "name": "test"}
        result = DataSanitizer.sanitize(data, sensitive_keys={"custom_secret"})
        assert "custom_secret" not in result
        assert result["name"] == "test"

    def test_default_keys_not_removed_with_custom(self):
        """Default keys are not removed when custom set is provided."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"api_key": "value", "custom_key": "secret"}
        result = DataSanitizer.sanitize(data, sensitive_keys={"custom_key"})
        # With custom keys, default keys are not removed
        assert "api_key" in result
        assert "custom_key" not in result

    def test_empty_custom_keys_removes_nothing(self):
        """Empty custom key set removes nothing."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"api_key": "value", "password": "secret"}
        result = DataSanitizer.sanitize(data, sensitive_keys=set())
        assert "api_key" in result
        assert "password" in result


class TestSanitizeEmptyInputs:
    """Tests for empty inputs."""

    def test_empty_dict_returns_empty(self):
        """Empty dictionary returns empty dictionary."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        assert DataSanitizer.sanitize({}) == {}

    def test_empty_list_returns_empty(self):
        """Empty list returns empty list."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        assert DataSanitizer.sanitize([]) == []


class TestSanitizeOriginalUnmodified:
    """Tests that original data is not modified."""

    def test_original_dict_unchanged(self):
        """Original dictionary is not modified."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        original = {"name": "test", "api_key": "secret"}
        DataSanitizer.sanitize(original)
        assert "api_key" in original

    def test_original_nested_dict_unchanged(self):
        """Original nested dictionary is not modified."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        original = {"user": {"name": "test", "password": "secret"}}
        DataSanitizer.sanitize(original)
        assert "password" in original["user"]


class TestRedactBasicDictionary:
    """Tests for redacting basic dictionaries."""

    def test_redacts_api_key(self):
        """api_key value is redacted."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"username": "user", "api_key": "secret123"}
        result = DataSanitizer.redact(data)
        assert result["api_key"] == "[REDACTED]"
        assert result["username"] == "user"

    def test_redacts_password(self):
        """password value is redacted."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"username": "user", "password": "secret123"}
        result = DataSanitizer.redact(data)
        assert result["password"] == "[REDACTED]"
        assert result["username"] == "user"

    def test_redacts_multiple_keys(self):
        """Multiple sensitive keys are redacted."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {
            "api_key": "k1",
            "password": "p1",
            "secret": "s1",
            "name": "test",
        }
        result = DataSanitizer.redact(data)
        assert result["api_key"] == "[REDACTED]"
        assert result["password"] == "[REDACTED]"
        assert result["secret"] == "[REDACTED]"
        assert result["name"] == "test"


class TestRedactCustomText:
    """Tests for custom redaction text."""

    def test_custom_redaction_text(self):
        """Custom redaction text is used."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"api_key": "secret"}
        result = DataSanitizer.redact(data, redaction_text="***HIDDEN***")
        assert result["api_key"] == "***HIDDEN***"

    def test_empty_redaction_text(self):
        """Empty redaction text is used."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"api_key": "secret"}
        result = DataSanitizer.redact(data, redaction_text="")
        assert result["api_key"] == ""


class TestRedactNestedStructures:
    """Tests for redacting nested structures."""

    def test_redacts_nested_dict(self):
        """Nested dictionary values are redacted."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"config": {"api_key": "secret", "url": "http://example.com"}}
        result = DataSanitizer.redact(data)
        assert result["config"]["api_key"] == "[REDACTED]"
        assert result["config"]["url"] == "http://example.com"

    def test_redacts_list_of_dicts(self):
        """List of dictionaries values are redacted."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = [
            {"name": "a", "password": "p1"},
            {"name": "b", "password": "p2"},
        ]
        result = DataSanitizer.redact(data)
        assert result[0]["password"] == "[REDACTED]"
        assert result[1]["password"] == "[REDACTED]"
        assert result[0]["name"] == "a"


class TestRedactPreservesStructure:
    """Tests that redact preserves data structure."""

    def test_preserves_key_in_result(self):
        """Redacted key is still present in result."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"api_key": "secret"}
        result = DataSanitizer.redact(data)
        assert "api_key" in result

    def test_preserves_nested_structure(self):
        """Nested structure is preserved."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"a": {"b": {"password": "secret"}}}
        result = DataSanitizer.redact(data)
        assert "a" in result
        assert "b" in result["a"]
        assert "password" in result["a"]["b"]


class TestConvenienceFunctions:
    """Tests for convenience functions."""

    def test_sanitize_data_function(self):
        """sanitize_data convenience function works."""
        from local_deep_research.security.data_sanitizer import sanitize_data

        data = {"api_key": "secret", "name": "test"}
        result = sanitize_data(data)
        assert "api_key" not in result
        assert result["name"] == "test"

    def test_redact_data_function(self):
        """redact_data convenience function works."""
        from local_deep_research.security.data_sanitizer import redact_data

        data = {"api_key": "secret", "name": "test"}
        result = redact_data(data)
        assert result["api_key"] == "[REDACTED]"
        assert result["name"] == "test"

    def test_sanitize_data_with_custom_keys(self):
        """sanitize_data works with custom keys."""
        from local_deep_research.security.data_sanitizer import sanitize_data

        data = {"custom": "value", "other": "data"}
        result = sanitize_data(data, sensitive_keys={"custom"})
        assert "custom" not in result
        assert result["other"] == "data"

    def test_redact_data_with_custom_text(self):
        """redact_data works with custom redaction text."""
        from local_deep_research.security.data_sanitizer import redact_data

        data = {"password": "secret"}
        result = redact_data(data, redaction_text="<removed>")
        assert result["password"] == "<removed>"


class TestDefaultSensitiveKeys:
    """Tests for the default sensitive keys constant."""

    def test_default_keys_include_api_key(self):
        """Default keys include api_key."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        assert "api_key" in DataSanitizer.DEFAULT_SENSITIVE_KEYS

    def test_default_keys_include_password(self):
        """Default keys include password."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        assert "password" in DataSanitizer.DEFAULT_SENSITIVE_KEYS

    def test_default_keys_include_secret(self):
        """Default keys include secret."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        assert "secret" in DataSanitizer.DEFAULT_SENSITIVE_KEYS

    def test_default_keys_is_set(self):
        """Default keys is a set for O(1) lookup."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        assert isinstance(DataSanitizer.DEFAULT_SENSITIVE_KEYS, set)


class TestEdgeCases:
    """Tests for edge cases."""

    def test_handles_none_values_in_dict(self):
        """Handles None values in dictionary."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"name": None, "api_key": "secret"}
        result = DataSanitizer.sanitize(data)
        assert result["name"] is None
        assert "api_key" not in result

    def test_handles_numeric_values(self):
        """Handles numeric values in dictionary."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"count": 42, "api_key": "secret"}
        result = DataSanitizer.sanitize(data)
        assert result["count"] == 42
        assert "api_key" not in result

    def test_handles_boolean_values(self):
        """Handles boolean values in dictionary."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = {"enabled": True, "password": "secret"}
        result = DataSanitizer.sanitize(data)
        assert result["enabled"] is True
        assert "password" not in result

    def test_handles_mixed_types_in_list(self):
        """Handles mixed types in list."""
        from local_deep_research.security.data_sanitizer import DataSanitizer

        data = [1, "string", {"api_key": "secret"}, None, True]
        result = DataSanitizer.sanitize(data)
        assert result[0] == 1
        assert result[1] == "string"
        assert "api_key" not in result[2]
        assert result[3] is None
        assert result[4] is True
