"""FROZEN VERBATIM COPY of NEOva2's pure proof-bundle verifier.

Source: hashnet-colab/neova2 main `4183946` —
  `neova/neova/proofs.py::verify_bundle` (+ its constants) and the minimal
  primitives it calls from `neova/neova/witness.py` (RFC 6962 Merkle,
  ClosedRecord, Attestation, confirm) and `neova/neova/closing.py`
  (TierRecord). Nothing else; nothing changed beyond imports/layout.

WHY A COPY AND NOT AN IMPORT: the backend must judge a readback bundle
cryptographically BEFORE attesting (an attestation gated only on structure
would accept a forged bundle), and cotrugli-ledger's CI has no neova2
checkout to import from. The same frozen-copy discipline as the door verb
in tests/test_neova2_truck_anchor.py applies: do NOT "simplify" this to
call our own code, and re-freeze against neova2 when the upstream verifier
changes. Drift guard: tests judge the REAL live-fleet bundle
(tests/fixtures/neova2_live_bundle_2026-07-25.json, produced and
witnessed by the live fleet on 2026-07-25) with THIS copy — if the copy
drifts from what the fleet emits, that test breaks first.

`verify_bundle(bundle, trusted_registry)` is a PURE function: commitment
membership in the range root, BOTH witness signatures (two different
qualified masters, the WaW built over the base attestation), every ladder
step, and the honesty flags. `trusted_registry` maps witness_id BYTES ->
raw Ed25519 public key bytes (or key objects) and is the PINNED trust
anchor obtained out of band — never from the bundle. Fail-closed.
"""

from __future__ import annotations

import hashlib
import struct
from dataclasses import dataclass

from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey

FORMAT = "neova2-proof-bundle-v1"
_TIERS_UP = ["HOUR", "DAY", "QUARTER", "ANNUAL"]


def _sha(*parts: bytes) -> bytes:
    h = hashlib.sha256()
    for p in parts:
        h.update(p)
    return h.digest()


def _unhx(s: str) -> bytes:
    return bytes.fromhex(s)


# ---- RFC 6962-style Merkle over the ordered 32-byte commitments (witness.py) ----
def _leaf(b: bytes) -> bytes:
    return _sha(b"\x00", b)


def _node(left: bytes, right: bytes) -> bytes:
    return _sha(b"\x01", left, right)


def merkle_root(leaves: list) -> bytes:
    if not leaves:
        return _sha(b"")                     # empty range = well-defined root
    level = [_leaf(x) for x in leaves]
    while len(level) > 1:
        nxt = []
        for i in range(0, len(level), 2):
            if i + 1 < len(level):
                nxt.append(_node(level[i], level[i + 1]))
            else:
                nxt.append(level[i])         # odd node promoted (RFC 6962)
        level = nxt
    return level[0]


def merkle_proof(leaves: list, index: int) -> list:
    """Audit path for `index`: list of (is_right_sibling, hash)."""
    path = []
    level = [_leaf(x) for x in leaves]
    i = index
    while len(level) > 1:
        nxt = []
        for j in range(0, len(level), 2):
            if j + 1 < len(level):
                node = _node(level[j], level[j + 1])
                if j == i:
                    path.append((True, level[j + 1]))
                elif j + 1 == i:
                    path.append((False, level[j]))
            else:
                node = level[j]
            nxt.append(node)
        i //= 2
        level = nxt
    return path


def verify_membership(leaf_value: bytes, index: int, proof: list,
                      root: bytes) -> bool:
    h = _leaf(leaf_value)
    for is_right, sib in proof:
        h = _node(h, sib) if is_right else _node(sib, h)
    return h == root


@dataclass(frozen=True)
class ClosedRecord:
    """The closed set the witnesses attest (witness.py)."""
    range_start: int
    count: int
    object_root: bytes            # 32 B, Merkle root of the range
    prev_record_hash: bytes       # 32 B link (all-zero for the first)

    def record_hash(self) -> bytes:
        return _sha(b"NVREC1",
                    struct.pack(">QQ", self.range_start, self.count),
                    self.object_root, self.prev_record_hash)


@dataclass(frozen=True)
class Attestation:
    witness_id: bytes
    kind: str                     # "BASE" or "WAW"
    signature: bytes


CONFIRMED = "CONFIRMED"
UNCONFIRMED = "UNCONFIRMED"


@dataclass(frozen=True)
class ConfirmResult:
    status: str
    reason: str = ""


def confirm(record: ClosedRecord, base: Attestation,
            waw: Attestation, qualified: dict) -> ConfirmResult:
    """A record is CONFIRMED iff base and waw come from TWO DIFFERENT
    qualified witnesses, the base signature verifies over the record, and
    the waw signature verifies over (record + base attestation)."""
    if base.kind != "BASE" or waw.kind != "WAW":
        return ConfirmResult(UNCONFIRMED, "wrong attestation kinds")
    if base.witness_id == waw.witness_id:
        return ConfirmResult(UNCONFIRMED, "same witness cannot self-confirm")
    if base.witness_id not in qualified or waw.witness_id not in qualified:
        return ConfirmResult(UNCONFIRMED, "unqualified witness")
    rh = record.record_hash()
    try:
        qualified[base.witness_id].verify(base.signature, rh)
    except InvalidSignature:
        return ConfirmResult(UNCONFIRMED, "base signature invalid")
    payload = _sha(rh, base.witness_id, base.signature)
    try:
        qualified[waw.witness_id].verify(waw.signature, payload)
    except InvalidSignature:
        return ConfirmResult(UNCONFIRMED, "waw signature invalid")
    return ConfirmResult(CONFIRMED)


@dataclass(frozen=True)
class TierRecord:
    """One closing record at any tier (closing.py). `root` is the Merkle
    root over the CHILD record hashes (roots, not objects)."""
    tier: str
    period_id: int
    first_position: int
    last_position: int
    object_count: int
    n_children: int
    root: bytes                    # Merkle over child record_hashes
    prev_hash: bytes               # link to the previous record of this tier

    def record_hash(self) -> bytes:
        return _sha(b"NVTIER1", self.tier.encode(),
                    struct.pack(">QQQQQ", self.period_id, self.first_position,
                                self.last_position, self.object_count,
                                self.n_children),
                    self.root, self.prev_hash)


# ---------------------------------------------------------------- verifier
def verify_bundle(bundle: dict, trusted_registry: dict | None = None
                  ) -> dict:
    """Independent verification from the bundle alone (plus an optional
    PINNED registry — the anchor the verifier received through Cotrugli
    Ledger / the Chamber, NOT from the bundle). Checks: commitment
    membership in the range root, BOTH witness signatures (two different
    qualified masters, the WaW built over the base attestation), every
    ladder step, and the honesty flags. Fail-closed."""
    def bad(reason):
        return {"valid": False, "reason": reason}
    try:
        if bundle.get("format") != FORMAT:
            return bad("unknown bundle format")
        if bundle.get("eraseal") is not None:
            return bad("bundle claims an EraSeal — none can exist yet")
        commitment = _unhx(bundle["commitment"])
        rr = bundle["range_record"]
        rec = ClosedRecord(rr["range_start"], rr["count"],
                           _unhx(rr["object_root"]),
                           _unhx(rr["prev_record_hash"]))
        pos = bundle["position"]
        li = bundle["membership"]["leaf_index"]
        if pos != rec.range_start + li or not 0 <= li < rec.count:
            return bad("position does not match the range")
        proof = [(bool(r), _unhx(h))
                 for r, h in bundle["membership"]["proof"]]
        if not verify_membership(commitment, li, proof, rec.object_root):
            return bad("membership proof invalid")
        atts = [Attestation(a["witness_id"].encode("utf-8"), a["kind"],
                            _unhx(a["signature"]))
                for a in bundle["attestations"]]
        base = next((a for a in atts if a.kind == "BASE"), None)
        waw = next((a for a in atts if a.kind == "WAW"), None)
        if base is None or waw is None:
            return bad("missing attestation")
        embedded = {wid.encode("utf-8"): _unhx(hx)
                    for wid, hx in bundle["qualified"].items()}
        if trusted_registry is not None:
            pinned = {wid: (pub.public_bytes_raw()
                            if hasattr(pub, "public_bytes_raw") else pub)
                      for wid, pub in trusted_registry.items()}
            if embedded != pinned:
                return bad("qualified registry does not match the PINNED "
                           "registry — refusing (possible impostor set)")
        qualified = {wid: Ed25519PublicKey.from_public_bytes(raw)
                     for wid, raw in embedded.items()}
        res = confirm(rec, base, waw, qualified)
        if res.status != CONFIRMED:
            return bad(f"witness confirmation failed: {res.reason}")
        child_hash = rec.record_hash()
        expect = 0
        for step in bundle["ladder"]:
            tr = step["record"]
            trec = TierRecord(tr["tier"], tr["period_id"],
                              tr["first_position"], tr["last_position"],
                              tr["object_count"], tr["n_children"],
                              _unhx(tr["root"]), _unhx(tr["prev_hash"]))
            if trec.tier not in _TIERS_UP[expect:]:
                return bad("ladder tiers out of order")
            expect = _TIERS_UP.index(trec.tier) + 1
            sproof = [(bool(r), _unhx(h)) for r, h in step["proof"]]
            if not verify_membership(child_hash, step["child_index"],
                                     sproof, trec.root):
                return bad(f"{trec.tier} ladder step invalid")
            child_hash = trec.record_hash()
        top = bundle["ladder"][-1]["tier"] if bundle["ladder"] else "RANGE"
        if top != bundle.get("closed_up_to"):
            return bad("closed_up_to does not match the ladder")
        want_open = _TIERS_UP[_TIERS_UP.index(top) + 1:] \
            if top != "RANGE" else list(_TIERS_UP)
        if bundle.get("not_closed") != want_open:
            return bad("not_closed does not match the ladder")
        return {"valid": True, "position": pos, "closed_up_to": top,
                "not_closed": want_open,
                "batch": bundle.get("batch"),
                "confirmed_by": sorted(a["witness_id"]
                                       for a in bundle["attestations"])}
    except (KeyError, ValueError, TypeError, struct.error) as e:
        return bad(f"malformed bundle: {type(e).__name__}")
