"""VEB hash derivation (Appendix A.2). Every digest goes through the A1 primitive (id inside the hashed,
domain-separated canonical content), so the algorithm is inseparable from the bytes and a widening is a clean
new profile. `content_hash` ⟂ `artifact_hash`; the anchoring batch carries `artifact_hash` leaves whose
`batch_root` is the opaque value crossing to NEO's AnchoredRoot (#145, A2)."""

from __future__ import annotations

from typing import Sequence

from cl.canonical.hash_profile import content_hash as _hash_by_profile
from cl.canonical.hash_profile import resolve_profile
from cl.model.veb import (
    DOMAIN_VEB_ARTIFACT,
    DOMAIN_VEB_CONTENT,
    DOMAIN_VEB_PROOFSET,
    VebContentV1,
)


def content_hash(veb: VebContentV1) -> bytes:
    """A.2: `HASH_BY_PROFILE(id, COTRUGLI:VEB:CONTENT:V1 ‖ canonical(content INCLUDING id))`."""
    return _hash_by_profile(veb.hash_profile_id, DOMAIN_VEB_CONTENT, veb.to_canonical_content())


def proof_set_hash(hash_profile_id: bytes, proofs: Sequence[dict] = ()) -> bytes:
    """The canonical commitment to the proof set. Unsigned → the canonical EMPTY proof set (A.2)."""
    content = {"hash_profile_id": hash_profile_id.hex(), "proofs": list(proofs)}
    return _hash_by_profile(hash_profile_id, DOMAIN_VEB_PROOFSET, content)


def artifact_hash(
    hash_profile_id: bytes,
    content_hash_bytes: bytes,
    proof_set_hash_bytes: bytes,
    verification_profile_ref: str,
) -> bytes:
    """A.2: `HASH_BY_PROFILE(id, content_hash ‖ proof_set_hash ‖ verification_profile_ref)`, realized as a
    domain-separated canonical object so the id stays inside the hashed content (A1)."""
    content = {
        "hash_profile_id": hash_profile_id.hex(),
        "content_hash": content_hash_bytes.hex(),
        "proof_set_hash": proof_set_hash_bytes.hex(),
        "verification_profile_ref": verification_profile_ref,
    }
    return _hash_by_profile(hash_profile_id, DOMAIN_VEB_ARTIFACT, content)


def event_id(hash_profile_id: bytes, content_hash_bytes: bytes) -> str:
    """`urn:cotrugli:veb:<profile-version-token>:<content_hash>` (Appendix A.2; #1 CONFIRM-WITH-CHANGE — a
    profile-UNIQUE version token, not the bare algorithm name)."""
    token = resolve_profile(hash_profile_id).version_token
    return f"urn:cotrugli:veb:{token}:{content_hash_bytes.hex()}"


def unsigned_artifact_hash(veb: VebContentV1, verification_profile_ref: str) -> bytes:
    """Convenience: the artifact hash of an UNSIGNED VEB (canonical empty proof set) — the lowest assurance
    level (A3). Signed artifacts pass their real proof set through `proof_set_hash`."""
    ch = content_hash(veb)
    ps = proof_set_hash(veb.hash_profile_id, ())
    return artifact_hash(veb.hash_profile_id, ch, ps, verification_profile_ref)
