"""``claim-lattice@v1`` π*: wraps
:func:`arborist.qa.parse_claims.parse_pointer_claims`.

Domain: ``text``. Input UTF-8 bytes are parsed into a list of
:class:`ParsedClaim` objects; the canonical projection is the
canonical-JSON serialization of the parsed list (sorted keys, no
whitespace).
"""

from __future__ import annotations

import json
from dataclasses import asdict, dataclass

from arborist.pi_star.protocol import PiStarError
from arborist.pi_star.registry import register


def _parsed_claim_to_dict(claim) -> dict:
    """Convert a ParsedClaim dataclass to a sorted-key-friendly dict.

    ParsedClaim shape (see ``arborist.qa.parse_claims``):
    ``claim_text``, ``pointer_ids``, ``parse_status``, ``raw_line``.
    """
    return {
        "claim_text": claim.claim_text,
        "pointer_ids": list(claim.pointer_ids),
        "parse_status": claim.parse_status,
        "raw_line": claim.raw_line,
    }


@dataclass
class ClaimLatticeV1:
    name: str = "claim-lattice"
    version: str = "v1"
    domain: str = "text"

    def canonicalize(self, raw: bytes) -> bytes:
        if not isinstance(raw, (bytes, bytearray)):
            raise PiStarError(
                "claim-lattice@v1 expects bytes; got "
                f"{type(raw).__name__}"
            )
        try:
            text = raw.decode("utf-8", errors="surrogatepass")
        except UnicodeDecodeError as exc:  # pragma: no cover
            raise PiStarError(f"input not valid UTF-8: {exc}") from exc

        from arborist.qa.parse_claims import parse_pointer_claims

        parsed = parse_pointer_claims(text)
        canon = [_parsed_claim_to_dict(c) for c in parsed]
        encoded = json.dumps(
            canon,
            sort_keys=True,
            separators=(",", ":"),
            ensure_ascii=False,
        )
        return encoded.encode("utf-8", errors="surrogatepass")


register(ClaimLatticeV1())
