"""Shared TypedDict contracts for snapshot payloads.

These types intentionally allow partial/malformed payloads so callers can
perform robust validation and fallback logic without assuming strict shape.
"""

from __future__ import annotations

from typing import Any, TypedDict


class ErrorCategoryDict(TypedDict, total=False):
    category: str
    suggestion: str


class ExceptionDict(TypedDict, total=False):
    type: str
    qualified_type: str
    message: str
    error_category: ErrorCategoryDict


class SourceLineDict(TypedDict, total=False):
    lineno: int
    code: str


class SourceDict(TypedDict, total=False):
    start: int
    end: int
    snippet: list[SourceLineDict]


class FrameDict(TypedDict, total=False):
    file: str
    file_rel: str
    line: int | str
    function: str
    module: str
    code: str
    source: SourceDict
    locals: dict[str, Any]
    locals_meta: dict[str, dict[str, Any]]
    args: dict[str, Any]
    args_meta: dict[str, dict[str, Any]]
    arg_names: list[str]
    is_coroutine: bool


class SessionDict(TypedDict, total=False):
    name: str
    timestamp_utc: str
    llmdebug_version: str


class SnapshotDict(TypedDict, total=False):
    # Legacy flat fields
    schema_version: str
    name: str
    timestamp_utc: str
    llmdebug_version: str
    exception: ExceptionDict
    traceback: str
    frames: list[FrameDict | Any]
    crash_frame_index: int | str
    capture_config: dict[str, Any]
    git: dict[str, Any]
    pytest: dict[str, Any]
    rca: dict[str, Any]
    hypothesis: str
    verification_result: dict[str, Any]
    trace: Any
    eval: Any
    # DebugSession envelope fields
    kind: str
    session: SessionDict
    snapshot: dict[str, Any]
    context: dict[str, Any]


__all__ = [
    "ErrorCategoryDict",
    "ExceptionDict",
    "FrameDict",
    "SessionDict",
    "SnapshotDict",
    "SourceDict",
    "SourceLineDict",
]
