"""Safety utilities for non-throwing public SDK operations."""

# TODO(phase-1): Add structured internal diagnostics once logger core exists.

from __future__ import annotations

from typing import Callable, TypeVar


T = TypeVar("T")
ErrorCallback = Callable[[Exception], None]


def safe_invoke(callback: ErrorCallback | None, exc: BaseException) -> None:
    """Invoke error callback defensively and never raise."""

    if callback is None:
        return
    wrapped_exc: Exception
    if isinstance(exc, Exception):
        wrapped_exc = exc
    else:
        wrapped_exc = Exception(str(exc))
    try:
        callback(wrapped_exc)
    except BaseException:
        return


def safe_call(
    fn: Callable[[], T],
    *,
    on_error: ErrorCallback | None = None,
    default: T | None = None,
) -> T | None:
    """Execute callable and return fallback value when any failure occurs."""

    try:
        return fn()
    except BaseException as exc:
        safe_invoke(on_error, exc)
        return default
