"""Canonical JSON serialization for manifests (RFC 8785 subset)."""

from __future__ import annotations

import json
from typing import Any, Dict, Union

from .schema import DocManifest, CollectionManifest


def canonical_json_bytes(obj: Dict[str, Any]) -> bytes:
    """Serialize to canonical JSON bytes.

    This uses sorted keys and compact separators, which matches JCS for
    simple object graphs used in v1 manifests (strings/ints/lists/objects).
    """
    text = json.dumps(
        obj,
        ensure_ascii=False,
        separators=(",", ":"),
        sort_keys=True,
    )
    return text.encode("utf-8")


def dump_manifest_bytes(manifest: DocManifest) -> bytes:
    return canonical_json_bytes(manifest.to_dict())


def dump_collection_bytes(manifest: CollectionManifest) -> bytes:
    return canonical_json_bytes(manifest.to_dict())


def load_manifest_bytes(data: bytes) -> DocManifest:
    obj = json.loads(data.decode("utf-8"))
    return DocManifest.from_dict(obj)


def load_collection_bytes(data: bytes) -> CollectionManifest:
    obj = json.loads(data.decode("utf-8"))
    return CollectionManifest.from_dict(obj)


def load_manifest_object(data: bytes) -> Dict[str, Any]:
    """Load a manifest JSON object without schema validation.

    Used for shallow integrity checks where only the manifest hash matters.
    """
    obj = json.loads(data.decode("utf-8"))
    if not isinstance(obj, dict):
        raise ValueError("manifest JSON must be an object")
    return obj
