"""Streaming JSON parser — handles incomplete JSON from LLM streaming."""

from __future__ import annotations

import json
from typing import Any


def parse_streaming_json(partial_json: str | None) -> Any:
    """Parse potentially incomplete JSON during streaming.

    Always returns a valid object, even if the JSON is incomplete.
    Falls back to empty dict on parse failure.
    """
    if not partial_json or partial_json.strip() == "":
        return {}

    # Try standard parsing first (fastest for complete JSON)
    try:
        return json.loads(partial_json)
    except (json.JSONDecodeError, ValueError):
        pass

    # Try to fix incomplete JSON by adding closing brackets
    try:
        return _parse_partial(partial_json)
    except Exception:
        return {}


def _parse_partial(text: str) -> Any:
    """Best-effort parsing of incomplete JSON."""
    text = text.strip()
    if not text:
        return {}

    # Try progressively adding closing delimiters
    stack: list[str] = []
    in_string = False
    escape_next = False

    for ch in text:
        if escape_next:
            escape_next = False
            continue
        if ch == "\\":
            escape_next = True
            continue
        if ch == '"' and not escape_next:
            in_string = not in_string
            continue
        if in_string:
            continue
        if ch in "{[":
            stack.append("}" if ch == "{" else "]")
        elif ch in "}]":
            if stack:
                stack.pop()

    # If we're in a string, close it
    suffix = ""
    if in_string:
        suffix += '"'

    # Close any remaining brackets
    suffix += "".join(reversed(stack))

    try:
        return json.loads(text + suffix)
    except (json.JSONDecodeError, ValueError):
        return {}
