"""Data sanitization utilities for logging and observability.

This module provides utilities to safely truncate and sanitize data
before logging or storing, preventing memory/storage explosions while
preserving useful debugging information.
"""

from typing import Any


def sanitize_for_logging(
    data: Any,
    *,
    max_depth: int = 4,
    max_str_len: int = 1000,
    max_list_len: int = 20,
) -> Any:
    """Sanitize data for logging - truncate large values, limit depth.

    This ensures observability data doesn't explode storage or memory
    while still providing useful debugging information.

    Args:
        data: Data to sanitize
        max_depth: Maximum nesting depth
        max_str_len: Maximum string length before truncation
        max_list_len: Maximum list length before truncation

    Returns
    -------
        Sanitized data structure
    """
    if max_depth <= 0:
        return {"_truncated": True, "_type": type(data).__name__}

    if data is None:
        return None

    if isinstance(data, (bool, int, float)):
        return data

    if isinstance(data, str):
        if len(data) > max_str_len:
            return data[:max_str_len] + f"... ({len(data)} chars total)"
        return data

    if isinstance(data, dict):
        result = {}
        for k, v in data.items():
            key = str(k) if not isinstance(k, str) else k
            result[key] = sanitize_for_logging(
                v,
                max_depth=max_depth - 1,
                max_str_len=max_str_len,
                max_list_len=max_list_len,
            )
        return result

    if isinstance(data, (list, tuple)):
        if len(data) > max_list_len:
            truncated = [
                sanitize_for_logging(
                    item,
                    max_depth=max_depth - 1,
                    max_str_len=max_str_len,
                    max_list_len=max_list_len,
                )
                for item in data[:max_list_len]
            ]
            truncated.append(f"... ({len(data)} items total)")
            return truncated
        return [
            sanitize_for_logging(
                item,
                max_depth=max_depth - 1,
                max_str_len=max_str_len,
                max_list_len=max_list_len,
            )
            for item in data
        ]

    # For other types, convert to string representation
    try:
        s = str(data)
        if len(s) > max_str_len:
            return s[:max_str_len] + f"... ({type(data).__name__})"
        return s
    except Exception:
        return f"<{type(data).__name__}>"
