"""RQ2-P3 mechanism instrument — the willing-bridge POOL topology, on SYNTHETIC
seeds ONLY (`rq2p3-mechanism-prereg.md` §3). No confirmatory record is read.

Pins: (a) the pool helpers `zipf_weights` / `weighted_draw` are deterministic and
well-formed; (b) the new `bridge-federated-pool` branch draws from a finite pool so
circuits genuinely REUSE bridges (label collisions → concentration variance), while
still spanning ≥2 houses and staying isolation-gated; (c) the existing lead
`bridge-federated` branch is left bit-reproducible (fresh bridge per seed, unchanged).
"""

import hashlib

from cmd_chat.sor.analysis.confirm_load_rq2 import bridge_concentration, bridge_label
from cmd_chat.sor.assembler import assemble, weighted_draw, zipf_weights
from cmd_chat.sor.battery import Cell, derive_seed


def _pool_cell(b, alpha):
    return Cell("RQ2P3", f"RQ2P3/B={b}/alpha={alpha}",
                {"bridge": "off", "topology": "bridge-federated-pool",
                 "selector": "static", "pool_B": str(b), "pool_alpha": str(alpha)}, False)


def _fed_cell():
    return Cell("RQ2", "RQ2/bridge=off/selector=static/topo=bridge-federated",
                {"bridge": "off", "topology": "bridge-federated", "selector": "static"}, False)


def _circuit_seeds(cell_id, n=50):
    run_seed = derive_seed(cell_id, 0)
    return [int.from_bytes(hashlib.sha256(f"{run_seed}|circ|{j}".encode()).digest()[:8], "big")
            for j in range(n)]


# --- pool helpers ---------------------------------------------------------- #
def test_zipf_weights_normalized_and_uniform_at_alpha0():
    w = zipf_weights(8, 0.0)
    assert len(w) == 8
    assert abs(sum(w) - 1.0) < 1e-12
    assert all(abs(x - 1.0 / 8) < 1e-12 for x in w)  # alpha=0 → uniform


def test_zipf_weights_skew_monotone_decreasing():
    w = zipf_weights(8, 2.0)
    assert abs(sum(w) - 1.0) < 1e-12
    assert all(w[i] > w[i + 1] for i in range(len(w) - 1))  # rank-1 heaviest
    assert w[0] > zipf_weights(8, 0.0)[0]  # skew concentrates mass on top bridge


def test_weighted_draw_deterministic_and_respects_extreme_skew():
    d = hashlib.sha256(b"x").hexdigest()
    assert weighted_draw(d, [0.25, 0.25, 0.25, 0.25]) == weighted_draw(d, [0.25, 0.25, 0.25, 0.25])
    # all mass on bin 0 → always bin 0, whatever the hash
    for s in (b"a", b"b", b"c", b"zzz"):
        assert weighted_draw(hashlib.sha256(s).hexdigest(), [1.0, 0.0, 0.0]) == 0


# --- the pool topology ----------------------------------------------------- #
def test_pool_reuses_bridges_and_labels_stay_in_range():
    cell = _pool_cell(4, 0.0)
    specs = [assemble(cell, s) for s in _circuit_seeds(cell.cell_id)]
    labels = {bridge_label(s) for s in specs}
    # B=4 pool over 50 circuits → far fewer distinct bridges than circuits (reuse),
    # and every label is one of the B pool slots.
    assert labels <= {f"bridge#{i:02d}" for i in range(4)}
    assert 1 < len(labels) <= 4
    assert len(labels) < len(specs)


def test_pool_produces_concentration_variance_unlike_fresh_bridge():
    cell = _pool_cell(4, 1.0)
    specs = [assemble(cell, s) for s in _circuit_seeds(cell.cell_id)]
    conc = [c for c in bridge_concentration(specs) if c is not None]
    assert len(conc) == len(specs)
    assert max(conc) > min(conc)  # genuine variance (the fresh-bridge instrument had none)


def test_pool_spans_two_houses_and_is_isolation_gated():
    cell = _pool_cell(8, 2.0)
    spec = assemble(cell, derive_seed(cell.cell_id, 0))
    assert spec.span_houses() >= 2
    assert spec.isolation_gated()
    assert spec.bridge_present and not spec.padding_applied
    assert any(h.is_bridge for h in spec.hops)


def test_pool_assembly_is_deterministic():
    cell = _pool_cell(4, 1.0)
    s = derive_seed(cell.cell_id, 0)
    assert assemble(cell, s).fingerprint() == assemble(cell, s).fingerprint()


# --- lead bridge-federated branch untouched (bit-reproducible) ------------- #
def test_lead_bridge_federated_still_fresh_bridge_per_seed():
    cell = _fed_cell()
    seeds = _circuit_seeds(cell.cell_id)
    specs = [assemble(cell, s) for s in seeds]
    labels = [bridge_label(s) for s in specs]
    # fresh bridge per seed → all-distinct labels (the lead degeneracy), NOT pool slots
    assert len(set(labels)) == len(labels)
    assert all(not lbl.startswith("bridge#00") or len(lbl) > 9 for lbl in labels)


def test_lead_bridge_federated_fingerprint_reproducible():
    cell = _fed_cell()
    s = derive_seed(cell.cell_id, 0)
    assert assemble(cell, s).fingerprint() == assemble(cell, s).fingerprint()
