"""Shared parsers for API responses and SDK events."""

from __future__ import annotations

import json
from typing import Literal, TypedDict, cast

# --- Cloudflare Sandbox SSE event types ---

# A JSON object from the wire — values are unknown but we know it's a dict
JSONObject = dict[str, object]


class StderrEvent(TypedDict):
    type: Literal['stderr']
    data: str


class StdoutEvent(TypedDict):
    type: Literal['stdout']
    data: str


class CompleteEvent(TypedDict):
    type: Literal['complete']
    exitCode: int


class ErrorEvent(TypedDict):
    type: Literal['error']
    message: str


SSEEvent = StderrEvent | StdoutEvent | CompleteEvent | ErrorEvent


class SDKEvent(TypedDict):
    event: str
    data: JSONObject
    ts: str


def parse_sse_event(raw: str) -> SSEEvent | None:
    """Parse a raw SSE data string into a typed event, or None if invalid."""
    try:
        data: object = json.loads(raw)  # pyright: ignore[reportAny]
    except (json.JSONDecodeError, TypeError):
        return None
    if not isinstance(data, dict) or 'type' not in data:
        return None
    return cast(SSEEvent, cast(object, data))


# --- SDK JSONL events (emitted to stdout by configure_jsonl_output) ---


def parse_sdk_event(line: str) -> SDKEvent | None:
    """Parse a JSONL line from SDK stdout into a typed event."""
    line = line.strip()
    if not line:
        return None
    try:
        data: object = json.loads(line)  # pyright: ignore[reportAny]
    except (json.JSONDecodeError, TypeError):
        return None
    if not isinstance(data, dict) or 'event' not in data:
        return None
    return cast(SDKEvent, cast(object, data))


# --- D1 response helpers ---


def parse_json_field(val: object) -> list[str]:
    """Parse a D1 JSON string field into a list.

    D1 stores arrays as JSON strings (e.g. '["sales"]').
    This handles both raw lists and JSON-encoded strings.
    """
    items: list[object] = []
    if isinstance(val, list):
        items = cast(list[object], val)
    elif isinstance(val, str):
        try:
            parsed: object = json.loads(val)  # pyright: ignore[reportAny]
            if isinstance(parsed, list):
                items = cast(list[object], parsed)
        except (json.JSONDecodeError, TypeError):
            return []
    else:
        return []
    return [str(item) for item in items]
