"""Fast JSON encoder/decoder shim for foundation/io hot paths.

Tries ``orjson`` (Rust-backed, 5-10x faster than stdlib) first; falls back
to the standard-library ``json`` module transparently.

Profiling baseline (from #1467 hot-path report):
  - stdlib json roundtrip: 25.96 µs
  - orjson target:         < 5 µs

Attributes:
    JSON_BACKEND: str
        Either ``"orjson"`` or ``"stdlib"``.  Exposed so callers and tests
        can assert or branch on the active backend.

Typical usage::

    from sage.libs.foundation.io._fast_json import loads, dumps, JSON_BACKEND

    data = loads('{"key": "value"}')
    raw_bytes = dumps({"key": "value"})   # always returns bytes
    text = dumps_str({"key": "value"})    # always returns str
"""

from __future__ import annotations

from typing import Any

# ---------------------------------------------------------------------------
# Backend selection — attempt orjson, fall back to stdlib
# ---------------------------------------------------------------------------

try:
    import orjson as _orjson

    def loads(s: str | bytes) -> Any:
        """Parse JSON string or bytes into a Python object (orjson backend)."""
        return _orjson.loads(s)

    def dumps(obj: Any, *, default: Any = None) -> bytes:
        """Serialize *obj* to JSON bytes (orjson backend).

        Args:
            obj: Python object to serialize.
            default: Callable for non-serializable types (same as orjson convention).

        Returns:
            UTF-8 encoded JSON bytes.
        """
        if default is not None:
            return _orjson.dumps(obj, default=default)
        return _orjson.dumps(obj)

    def dumps_str(obj: Any, *, default: Any = None) -> str:
        """Serialize *obj* to a JSON string (orjson backend)."""
        return dumps(obj, default=default).decode()

    JSON_BACKEND: str = "orjson"

except ImportError:
    import json as _json

    def loads(s: str | bytes) -> Any:  # type: ignore[misc]
        """Parse JSON string or bytes into a Python object (stdlib backend)."""
        if isinstance(s, (bytes, bytearray)):
            s = s.decode()
        return _json.loads(s)

    def dumps(obj: Any, *, default: Any = None) -> bytes:  # type: ignore[misc]
        """Serialize *obj* to JSON bytes (stdlib backend).

        Returns:
            UTF-8 encoded JSON bytes (to match the orjson return type).
        """
        return _json.dumps(obj, default=default).encode()

    def dumps_str(obj: Any, *, default: Any = None) -> str:  # type: ignore[misc]
        """Serialize *obj* to a JSON string (stdlib backend)."""
        return _json.dumps(obj, default=default)

    JSON_BACKEND = "stdlib"
