"""Embedded fallback counts for the six Belenos hardware experiments.

The measured per-output-port single-photon distributions ship in
`data/raw_port_counts.csv` and are loaded through `data_io.py`; the integer
event counts in this module are a summary-level fallback used only when that
file is absent.  Re-running the analysis on these counts reproduces every
tabulated p_hat, Wilson interval, suppression ratio, and correlation.

Each record carries the dump/syndrome event count `x` on the relevant port
out of `n` postselected single-photon detections.  For the Exp. 5B selectivity
rows, `x` and `n` are the within-syndrome counts (`ports[target_port]` and
`ports 0-3`) and `extra["events"]` carries the full postselected single-photon
total so that event-count totals remain correct.
"""

from __future__ import annotations

from dataclasses import dataclass, field


@dataclass(frozen=True)
class Row:
    label: str
    x: int            # events on the relevant (dump or syndrome) port
    n: int            # postselected single-photon detections
    expected: float | None = None   # ideal probability, if defined
    kind: str = ""                  # control / neutral / dc / code ...
    port: int | None = None         # dominant/target port, where relevant
    extra: dict = field(default_factory=dict)


# --------------------------------------------------------------------------
# Experiment 1: BALANCE separator (80,000 events; 8 inputs, ~10,000 each).
# Per-mode dump counts (port 0) from jobs RS_BALANCE_mode0..7; the summary
# statistics are kept for cross-checking.
# --------------------------------------------------------------------------
EXP1_SUMMARY = {
    "n_per_input": 10_000,
    "n_inputs": 8,
    "mean_dump": 0.188,          # mean over the 8 inputs
    "across_mode_std": 0.030,    # spread quoted as +/- in the text
    "ideal": 0.125,
    "best_input_dump": 0.140,    # best-performing input, CI [0.133, 0.147]
    "all_dominant_ports_correct": True,
}
EXP1_PER_MODE: list[Row] = [
    Row("input mode 0", 1929, 9993, expected=0.125, kind="control", port=0),
    Row("input mode 1", 1568, 9994, expected=0.125, kind="control", port=0),
    Row("input mode 2", 1397, 9992, expected=0.125, kind="control", port=0),
    Row("input mode 3", 1781, 9990, expected=0.125, kind="control", port=0),
    Row("input mode 4", 1879, 9992, expected=0.125, kind="control", port=0),
    Row("input mode 5", 2371, 9995, expected=0.125, kind="control", port=0),
    Row("input mode 6", 2242, 9995, expected=0.125, kind="control", port=0),
    Row("input mode 7", 1860, 9991, expected=0.125, kind="control", port=0),
]


# --------------------------------------------------------------------------
# Experiment 2: Neutral-state heralding (Table II, 50,000 events).
# Dump = port 0.  Three neutral inputs + non-neutral control + pure DC.
# --------------------------------------------------------------------------
EXP2 = [
    Row("Control (non-neutral)", 1906, 9_998, expected=0.125, kind="control"),
    Row("|0> - |1>",               73, 9_998, expected=0.0,   kind="neutral"),
    Row("|0> - |4>",                2, 9_995, expected=0.0,   kind="neutral"),
    Row("Balanced 4+4-",          106, 9_993, expected=0.0,   kind="neutral"),
    Row("Uniform (pure DC)",     9795, 9_996, expected=1.0,   kind="dc"),
]


# --------------------------------------------------------------------------
# Experiment 3: Proportional error detection (Table III, 70,000 events).
# Controlled DC contamination strength c; dump probability per row, n=10,000.
# --------------------------------------------------------------------------
EXP3_C = [0.00, 0.05, 0.10, 0.20, 0.40, 0.80, 1.60]
EXP3 = [
    Row("c=0.00",   70, 9_998),
    Row("c=0.05",  148, 9_995),
    Row("c=0.10",  200, 9_993),
    Row("c=0.20",  375, 9_997),
    Row("c=0.40", 1874, 9_995),
    Row("c=0.80", 4362, 9_992),
    Row("c=1.60", 8135, 9_991),
]


# --------------------------------------------------------------------------
# Experiment 4: Neutral-sector unitary core (Table IV / Fig. 3, 60,000 events).
# Dump = port 0 at 0,1,2,3 applications of R_N, plus two non-neutral controls.
# --------------------------------------------------------------------------
EXP4 = [
    Row("Neutral, 0x core",   75, 9_995, kind="neutral", port=0,
        extra={"depth": 0}),
    Row("Neutral, 1x core",    4, 9_995, kind="neutral", port=0,
        extra={"depth": 1}),
    Row("Neutral, 2x core",   18, 9_997, kind="neutral", port=0,
        extra={"depth": 2}),
    Row("Neutral, 3x core",    2,  9_999, kind="neutral", port=0,
        extra={"depth": 3}),
    Row("Control, 0x core", 1956,  9_996, kind="control", port=0),
    Row("Control, 1x core", 1896,  9_998, kind="control", port=0),
]


# --------------------------------------------------------------------------
# Experiment 5A: Parity-checked-subspace heralding (Table V, 40,000 events).
# Syndrome = total on ports 0-3; each code state has a dominant code port and
# a code-side fidelity (recorded directly from the paper).
# --------------------------------------------------------------------------
EXP5A = [
    Row("b0+b1",       90,  9_990, kind="code", port=4, extra={"fidelity": 0.988}),
    Row("b0+b2",      616,  9_993, kind="code", port=5, extra={"fidelity": 0.910}),
    Row("b1+b2",      108, 10_000, kind="code", port=6, extra={"fidelity": 0.969}),
    Row("b0+b1+b2",   115,  9_999, kind="code", port=7, extra={"fidelity": 0.936}),
]


# --------------------------------------------------------------------------
# Experiment 5B: Selective parity detection (~30,000 events).
# Each single-parity-violating input activates one syndrome port.  Selectivity
# is the within-syndrome ratio x = ports[target_port], n = ports 0-3; the full
# postselected single-photon total per input is kept in extra["events"].
# --------------------------------------------------------------------------
EXP5B = [
    Row("|0>-|1> (Sx)", 3135, 3184, kind="syndrome", port=1,
        extra={"expected_port": 1, "events": 9995}),
    Row("|0>-|2> (Sy)", 2579, 2732, kind="syndrome", port=2,
        extra={"expected_port": 2, "events": 9998}),
    Row("|0>-|4> (Sz)", 3830, 4066, kind="syndrome", port=3,
        extra={"expected_port": 3, "events": 9994}),
]

# Experiment 5C: non-neutral control syndrome leakage for the suppression ratio.
EXP5C_CONTROL = Row("Non-neutral control (syndrome)", 5497, 9997,
                    kind="control")


# --------------------------------------------------------------------------
# Experiment 6: Hong-Ou-Mandel control (~20,000 events).
# Identical circuit/preparation across three chip states; dump = port 0.  The
# calibrated state reuses the Apr-4 |0>-|1> neutral job; degraded and restored
# used n = 5,000 single-photon detections each.
# --------------------------------------------------------------------------
EXP6 = [
    Row("Calibrated (Apr 4)",   73, 9_998, kind="calibrated",
        extra={"hom_visibility": 0.907}),
    Row("Degraded (Apr 5-6)", 2405, 5_000, kind="degraded",
        extra={"hom_visibility": 0.212}),
    Row("Restored (Apr 6)",     29, 5_000, kind="restored",
        extra={"hom_visibility": 0.91, "hom_from_calibration_report": True}),
]


# --------------------------------------------------------------------------
# Device metadata reported by the Perceval remote-processor API for
# qpu:belenos (see Methods, "Operating conditions").
# --------------------------------------------------------------------------
DEVICE_METADATA = {
    "backend_id": "qpu:belenos",
    "backend_name": "Belenos QPU",
    "pcvl_version": "1.0.1",
    "clock_mhz": 4.94,
    "hom_visibility": 0.910,
    "g2_0": 0.019,
    "transmittance": 0.0484,
    "software_stack": {
        "mosaiq-belenos": "2.7.12",
        "hardware-core": "3.7.4",
        "pcvl-worker": "1.4.0",
        "perceval-quandela": "1.1.0",
        "universalchipworker": "1.7.0",
        "exqalibur": "1.1.1",
    },
}


def total_events() -> int:
    """Sum of per-configuration events across all experiments (~360k)."""
    groups = [EXP2, EXP3, EXP4, EXP5A, EXP5B, [EXP5C_CONTROL], EXP6]
    n = EXP1_SUMMARY["n_per_input"] * EXP1_SUMMARY["n_inputs"]
    for g in groups:
        n += sum(r.extra.get("events", r.n) for r in g)
    return n


if __name__ == "__main__":  # pragma: no cover
    print("summed per-configuration events:", f"{total_events():,}")
    print("conservative distinct total quoted in paper: > 340,000")
