#!/usr/bin/env python3
"""
verify_P062.py -- Addendum 62: G2/E6 threshold correction candidates.

Checks Candidate I (MU*pi/6), Candidate II (MU/2), the observational
uncertainty comparison, and the alternative-candidate table.
"""

import math
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))

PASS = FAIL = 0
_N = 0


def check(n, desc, cond):
    global PASS, FAIL
    ok = bool(cond)
    PASS += ok
    FAIL += not ok
    print(f"  [{'PASS' if ok else 'FAIL'}] {n:>2}. {desc}")
    return ok


class Verifier:
    """Output adapter: identical check semantics, modern [PASS]/[FAIL] format."""

    def __init__(self, name):
        print(name)

    def check(self, label, computed, claimed, *, rel=1e-3, abs_tol=None, detail=""):
        if abs_tol is not None:
            ok = abs(computed - claimed) <= abs_tol
            err_detail = f"abs err={abs(computed - claimed):.6g}, tol={abs_tol:.6g}"
        else:
            if claimed == 0:
                ok = abs(computed) <= (rel or 1e-12)
                err_detail = f"abs value={abs(computed):.6g}, tol={rel:.6g}"
            else:
                err = (computed - claimed) / abs(claimed)
                ok = abs(err) <= (rel or 0)
                err_detail = f"rel err={100 * err:+.6g}%, tol={100 * (rel or 0):.6g}%"
        return self.record(label, ok, computed, claimed, detail, err_detail)

    def record(self, label, ok, computed="", claimed="", detail="", err_detail=""):
        global _N
        _N += 1
        desc = label + (f" -- {detail}" if detail else "")
        check(_N, desc, ok)
        if computed != "" or claimed != "":
            print(f"        computed: {computed}")
            print(f"        claimed : {claimed}")
        if err_detail:
            print(f"        {err_detail}")
        return ok

    def summary(self):
        print(f"\n{'='*60}\nRESULT: {PASS} PASS / {FAIL} FAIL")
        return 1 if FAIL else 0


v = Verifier("P062 -- G2/E6 Threshold Correction")

ROOT = Path(__file__).resolve().parents[1]
TEX = (ROOT / "62_Addendum_ThresholdCorrection.tex").read_text()

PI = math.pi
MU0 = 4 * PI**3 + PI**2 + PI
MU1 = 16 * PI**3 / 5 + 3 * PI**2 / 4 + 2 * PI / 3
MU = MU1 / MU0
E_PL = 68.096
E_R_OBS = 56.502
SIGMA_E = 0.0088
EPS_TARGET = 0.406
DM31_FRAC = 0.014
MNU3_MEV = 49.5


def pct(value: float, target: float) -> float:
    return 100 * (value - target) / target


eps_1 = MU * PI / 6
eps_2 = MU / 2
gap_1 = 12 - eps_1
gap_2 = 12 - eps_2
e_r_1 = E_PL - gap_1
e_r_2 = E_PL - gap_2
res_1 = e_r_1 - E_R_OBS
res_2 = e_r_2 - E_R_OBS

v.check("mu0", MU0, 137.036304, rel=5e-8)
v.check("mu1", MU1, 108.716684, rel=5e-8)
v.check("MU", MU, 0.793338, rel=1e-5)
v.check("Candidate I epsilon", eps_1, 0.4154, rel=5e-4)
v.check("Candidate I gap", gap_1, 11.5846, rel=5e-5)
v.check("Candidate I E_R", e_r_1, 56.511, abs_tol=0.001)
v.check("Candidate I residual", res_1, 0.009, abs_tol=0.001)
v.check("Candidate II epsilon", eps_2, 0.3967, rel=5e-4)
v.check("Candidate II gap", gap_2, 11.6033, rel=5e-5)
v.check("Candidate II E_R", e_r_2, 56.493, abs_tol=0.001)
v.check("Candidate II residual", res_2, -0.009, abs_tol=0.001)
v.check("naive residual improvement factor", 0.406 / 0.009, 45.0, rel=5e-3)

sigma_from_dm31 = DM31_FRAC / (2 * MU)
v.check("E_R uncertainty from 1.4% Delta m31", sigma_from_dm31, 0.0088, rel=5e-3)
v.check("rounded residual sigma", 0.009 / 0.0088, 1.02, rel=5e-3)
v.check("Candidate I exact residual sigma", abs(res_1) / SIGMA_E, 1.02, rel=5e-2)
v.check("Candidate II exact residual sigma", abs(res_2) / SIGMA_E, 1.02, rel=5e-2)
v.record(
    "1.02 sigma is not within one sigma",
    0.009 / 0.0088 <= 1.0,
    f"0.009/0.0088 = {0.009 / 0.0088:.3f}",
    "<= 1.0",
    "Expected fail: the candidates are just outside 1 sigma, though still close to the boundary.",
)
v.record(
    "proof uses a one-sigma criterion",
    "Since $1.023 < 1.5$, both\ncandidates are within the $1\\sigma$ uncertainty band" not in TEX,
    "text says 1.023 < 1.5 implies within 1 sigma",
    "within 1 sigma requires <= 1",
    "Expected fail: the inequality shown supports a loose 1.5-sigma statement, not a one-sigma statement.",
)

required_frac_dm = 2 * MU * 0.003
v.check("Delta m31 precision needed for 3 sigma split", required_frac_dm, 0.0048, rel=1e-2)
sqrt_dm_precision_claim = 0.0047 * MNU3_MEV
sqrt_dm_precision_correct = 0.5 * 0.0047 * MNU3_MEV
v.check(
    "absolute sqrt(Delta m31) precision",
    sqrt_dm_precision_correct,
    0.23,
    rel=5e-2,
    detail="Expected fail: 0.47% precision on Delta m31 is only 0.235% on sqrt(Delta m31), about 0.12 meV, not 0.23 meV.",
)
v.check("paper's direct 0.47% times 49.5 meV", sqrt_dm_precision_claim, 0.23, rel=5e-2)

v.check("W(G2) order", 12, 12, rel=1e-12)
v.check("h dual E6", 12, 12, rel=1e-12)
v.check("G2 chamber angle pi/6 degrees", math.degrees(PI / 6), 30.0, rel=1e-12)
v.check("Candidate II mass correction exp(MU^2/2)", math.exp(MU**2 / 2), 1.370, rel=1e-3)
v.check("Candidate II / Candidate I ratio", eps_2 / eps_1, 3 / PI, rel=1e-12)
v.check("3/pi proximity to 1 percent", pct(3 / PI, 1.0), -4.5, rel=2e-2)

alternatives = {
    "pi/hdual_G2": PI / 4,
    "MU*pi/hdual_G2": MU * PI / 4,
    "pi/hdual_E6": PI / 12,
    "(hdual_E6-h_G2)/hdual_E6": 6 / 12,
    "MU/hdual_G2": MU / 4,
    "MU*sin(pi/h_G2)": MU * math.sin(PI / 6),
    "MU*cos(pi/h_G2)": MU * math.cos(PI / 6),
    "affine central charge ratio": MU * ((14 / 5) / 6),
}
claimed_values = {
    "pi/hdual_G2": 0.7854,
    "MU*pi/hdual_G2": 0.6231,
    "pi/hdual_E6": 0.2618,
    "(hdual_E6-h_G2)/hdual_E6": 0.5000,
    "MU/hdual_G2": 0.1983,
    "MU*sin(pi/h_G2)": 0.3967,
    "MU*cos(pi/h_G2)": 0.687,
    "affine central charge ratio": 0.370,
}
for name, target in claimed_values.items():
    v.check(f"alternative table {name}", alternatives[name], target, rel=2e-3)

v.record(
    "Phase 5b status remains conjectural",
    "Phase~5b (deriving $M_R$ from TOE constants) is not yet \\emph{closed}" in TEX,
    "not yet closed text present",
    "conjectural",
)

sys.exit(v.summary())
