"""S5 — Witness-about-Witness (POHAT testis testium).

The design's second intelligence: the sequencer decides the ORDER; this
decides the order is HONEST. Its whole strength is that the second witness
NEVER trusts the first — it independently reconstructs the same range's
object root from the same durable commitments and only then attests. A
forged root cannot be confirmed, because two independent honest witnesses
will not both derive a forged root from the real data.

BUILD PLAN v1.1 §7:
 1. The sequencer fixes an exact position range.
 2. A closed record is computed over that range: object root + link to the
    previous record.
 3. The first qualified witness signs the record (base witness).
 4. The second qualified witness INDEPENDENTLY reconstructs the same range
    and root.
 5. The second witness signs: the record + the first witness's signature +
    its own observation of the same result.
 6. Two matching independent attestations from two DIFFERENT qualified
    witnesses = CONFIRMED.
 7. A mismatch is never deleted: a third witness is called and the
    divergent evidence stays visible.

No per-object voting; witnessing applies to closed SETS. Hashes are
SHA-256 (CANON LOCK v1); the object root is an RFC 6962 Merkle tree so a
single object's membership in a confirmed record is provable.
"""

from __future__ import annotations

import hashlib
import struct
from dataclasses import dataclass

from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
    Ed25519PrivateKey, Ed25519PublicKey)


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


# ---- RFC 6962-style Merkle over the ordered 32-byte commitments ----
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]) -> 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[bytes], index: int) -> list[tuple]:
    """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. Its identity is its hash over
    the range, the object root and the previous record — so a different
    root over the same range is a DIFFERENT record (equivocation shows)."""
    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)


def build_record(range_start: int, commitments: list[bytes],
                 prev_record_hash: bytes) -> ClosedRecord:
    return ClosedRecord(range_start, len(commitments),
                        merkle_root(commitments), prev_record_hash)


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


@dataclass(frozen=True)
class Divergence:
    """Never deleted. A witness reconstructed a root that disagrees with
    the record — preserved for the third witness and the audit trail."""
    record_hash: bytes
    claimed_root: bytes
    reconstructed_root: bytes
    by_witness: bytes


class Witness:
    """One qualified witness master (nominally neo-5/6/7). Holds a signing
    key; POHAT decides which witnesses are qualified (registry passed to
    `confirm`)."""

    def __init__(self, witness_id: bytes, signing_key: Ed25519PrivateKey):
        self.witness_id = witness_id
        self._sk = signing_key

    def public_bytes(self) -> bytes:
        return self._sk.public_key().public_bytes_raw()

    def base_witness(self, record: ClosedRecord) -> Attestation:
        """Witness 1: sign the closed record."""
        return Attestation(self.witness_id, "BASE",
                           self._sk.sign(record.record_hash()))

    def witness_about_witness(self, record: ClosedRecord,
                              commitments: list[bytes],
                              first: Attestation,
                              first_pub: Ed25519PublicKey):
        """Witness 2: INDEPENDENTLY reconstruct the root from the same
        commitments; only if it matches the record AND the first witness's
        signature verifies does it attest (over record + first attestation
        + its own observation). A mismatch returns a Divergence — never a
        confirmation."""
        reconstructed = merkle_root(commitments)
        if reconstructed != record.object_root:
            return Divergence(record.record_hash(), record.object_root,
                              reconstructed, self.witness_id)
        try:
            first_pub.verify(first.signature, record.record_hash())
        except InvalidSignature:
            # the first attestation is not a valid base witness of THIS
            # record — refuse to build on it (no confirmation)
            return Divergence(record.record_hash(), record.object_root,
                              reconstructed, self.witness_id)
        payload = _sha(record.record_hash(), first.witness_id,
                       first.signature)
        return Attestation(self.witness_id, "WAW", self._sk.sign(payload))


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,
      * the waw signature verifies over (record + base attestation),
    i.e. two independent qualified masters attested the SAME record and the
    second built on the first's exact attestation. `qualified` maps
    witness_id -> Ed25519PublicKey (the POHAT-derived qualified set)."""
    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)
