"""
Role: Implements hydra_logger.extensions.security.data_redaction functionality for Hydra Logger.
Used By:
 - Internal `hydra_logger` modules importing this component.
Depends On:
 - re
 - typing
Notes:
 - Implements extension lifecycle or integration logic for data redaction.
"""

import re
from typing import Any, Dict, List, Optional


class DataRedaction:
    """
    Data redaction utility.

    Zero overhead when disabled.
    """

    def __init__(self, enabled: bool = False, patterns: Optional[List[str]] = None):
        """
        Initialize data redaction.

        Args:
            enabled: Whether redaction is enabled
            patterns: List of patterns to redact
        """
        self.enabled = enabled
        self.patterns = patterns or []
        self._max_depth = 16
        self._compiled_patterns: List[tuple] = []

        if self.enabled:
            self._compile_patterns()

    def _compile_patterns(self) -> None:
        """Compile regex patterns for performance."""
        pattern_map = {
            "email": (
                r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b",
                "[REDACTED_EMAIL]",
            ),
            "phone": (r"\b\d{3}[-.]?\d{3}[-.]?\d{4}\b", "[REDACTED_PHONE]"),
            "ssn": (r"\b\d{3}-\d{2}-\d{4}\b", "[REDACTED_SSN]"),
            "credit_card": (
                r"\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b",
                "[REDACTED_CARD]",
            ),
            "api_key": (r"\bsk-[A-Za-z0-9]{20,}\b", "[REDACTED_API_KEY]"),
            "password": (r'\bpassword["\s]*[:=]["\s]*[^\s]+', 'password="[REDACTED]"'),
            "token": (r'\btoken["\s]*[:=]["\s]*[^\s]+', 'token="[REDACTED]"'),
            "secret": (r'\bsecret["\s]*[:=]["\s]*[^\s]+', 'secret="[REDACTED]"'),
        }

        for pattern in self.patterns:
            if pattern in pattern_map:
                regex, replacement = pattern_map[pattern]
                self._compiled_patterns.append((re.compile(regex), replacement))

    def enable(self) -> None:
        """Enable redaction."""
        self.enabled = True
        self._compile_patterns()

    def disable(self) -> None:
        """Disable redaction."""
        self.enabled = False
        self._compiled_patterns.clear()

    def add_pattern(self, pattern: str, replacement: str = "[REDACTED]") -> None:
        """Add custom redaction pattern."""
        if self.enabled:
            self._compiled_patterns.append((re.compile(pattern), replacement))

    def redact(self, data: Any) -> Any:
        """
        Redact sensitive data.

        Args:
            data: Data to redact (string, dict, or other)

        Returns:
            Redacted data
        """
        if not self.enabled or not self._compiled_patterns:
            return data

        if isinstance(data, str):
            return self._redact_string(data)
        elif isinstance(data, dict):
            return self._redact_value(data, depth=0)
        else:
            return data

    def _redact_string(self, text: str) -> str:
        """Redact sensitive patterns in string."""
        result = text
        for pattern, replacement in self._compiled_patterns:
            result = pattern.sub(replacement, result)
        return result

    def _redact_dict(self, data: Dict[str, Any]) -> Dict[str, Any]:
        """Redact sensitive patterns in dictionary."""
        result = {}
        for key, value in data.items():
            result[key] = self._redact_value(value, depth=1)
        return result

    def _redact_value(self, value: Any, depth: int) -> Any:
        """Recursively redact supported container values with depth guard."""
        if depth > self._max_depth:
            return value

        if isinstance(value, str):
            return self._redact_string(value)
        if isinstance(value, dict):
            return {key: self._redact_value(item, depth + 1) for key, item in value.items()}
        if isinstance(value, list):
            return [self._redact_value(item, depth + 1) for item in value]
        if isinstance(value, tuple):
            return tuple(self._redact_value(item, depth + 1) for item in value)
        return value

    def is_enabled(self) -> bool:
        """Check if redaction is enabled."""
        return self.enabled
