from __future__ import annotations

from dataclasses import dataclass, asdict, is_dataclass
from typing import Optional, TypedDict, Union, cast, Any

from ..redact import RedactOption


class FriskOptionsDict(TypedDict, total=False):
    """Dictionary form of SDK redaction options."""

    redact_tool_args: Optional[RedactOption]
    redact_agent_state: Optional[RedactOption]


@dataclass
class FriskOptions:
    """Dataclass form of SDK redaction options."""

    redact_tool_args: Optional[RedactOption] = None
    redact_agent_state: Optional[RedactOption] = None


FriskOptionsInput = Union[FriskOptionsDict, FriskOptions, dict[str, Any], None]


def normalize_frisk_options(opts: object | None = None) -> FriskOptionsDict:
    """Normalize supported option input shapes into a stable options dictionary."""
    defaults: FriskOptionsDict = {"redact_tool_args": None, "redact_agent_state": None}

    if opts is None:
        return defaults
    if not isinstance(opts, type) and is_dataclass(opts):
        # asdict returns dict[str, Any]; cast to our stable output shape.
        return cast(FriskOptionsDict, asdict(cast(Any, opts)))

    # Treat anything else as mapping-like; dict(...) will raise TypeError otherwise.
    opts_dict = dict(cast(dict[str, Any], opts))
    merged = {**defaults, **opts_dict}
    return cast(FriskOptionsDict, merged)
