"""Sentinel value to distinguish between undefined, None, and actual values.

This module provides the UNDEFINED sentinel used to differentiate between:
- UNDEFINED: Field was not provided (default), should be excluded from API calls
- None: Field was explicitly set to null, should be sent as null to the API
- Value: Field was explicitly set to a value, should be sent to the API
"""

from typing import Any, Dict


class UndefinedType:
    """Sentinel type to represent undefined values.

    This is used as a default value instead of None to allow distinguishing
    between "not provided" (UNDEFINED) and "explicitly set to None" (None).
    """

    def __repr__(self) -> str:
        return "Undefined"

    def __str__(self) -> str:
        return "Undefined"


UNDEFINED: UndefinedType = UndefinedType()


def filter_undefined(data: Dict[str, Any]) -> Dict[str, Any]:
    """Remove undefined values from a dictionary.

    Keeps None values (explicitly set to null) and actual values.
    Only removes keys where the value is UNDEFINED (not provided).

    Args:
        data: Dictionary that may contain UNDEFINED values

    Returns:
        Dictionary with UNDEFINED values removed
    """
    return {k: v for k, v in data.items() if v is not UNDEFINED}
