#!/usr/bin/env python3
"""
verify_P093.py -- Addendum 93: Absolute M_W and M_Z.

This verifier checks the tree-level W/Z mass chain in
93_Addendum_WZMasses.tex.

The body calculation is mostly reproducible: the TOE NLO chain gives
M_W ~= 77.42 GeV and M_Z ~= 88.34 GeV. The audit flags stale abstract values,
an arithmetic typo in the explicit M_W^2 numerator, and an inconsistent
correction-sum table.
"""

import math
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))
from verify_common import Verifier, CheckResult


class ModernVerifier(Verifier):
    """Local adapter: modern check-line output format. Tolerance logic is
    inherited unchanged from verify_common.Verifier; only printing differs.
    Computed/claimed values stay as indented info lines."""

    def __init__(self, name: str) -> None:
        self.name = name
        self.results = []
        print(name)

    def record(self, label, ok, computed="", claimed="", detail=""):
        self.results.append(CheckResult(label, ok, computed, claimed, detail))
        status = "PASS" if ok else "FAIL"
        desc = f"{label} -- {detail}" if detail else label
        print(f"  [{status}] {len(self.results):>2}. {desc}")
        if computed != "" or claimed != "":
            print(f"          computed: {computed}")
            print(f"          claimed : {claimed}")
        return ok

    def summary(self) -> int:
        passed = sum(r.ok for r in self.results)
        failed = len(self.results) - passed
        print(f"\n{'='*60}\nRESULT: {passed} PASS / {failed} FAIL")
        return 1 if failed else 0


v = ModernVerifier("P093 -- Absolute W/Z Masses")

MU0 = 4 * math.pi**3 + math.pi**2 + math.pi
LAM = math.sin(math.pi / 14)
V = 246.22
MW_PDG = 80.377
MZ_PDG = 91.1876
MH0 = V / 2
MH1 = 125.53

sw = (1 / (1 + math.pi)) * (1 - 4 * LAM**2 / 5)
g2 = 4 * math.pi * (1 + math.pi) / (MU0 * (1 - 4 * LAM**2 / 5))
g = math.sqrt(g2)
mw_nlo = 0.5 * g * V
cosw = math.sqrt(1 - sw)
mz_nlo = mw_nlo / cosw
ratio_mw_mh = 2 * math.sqrt(math.pi * (1 + math.pi) / MU0)
mw_struct_mh0 = ratio_mw_mh * MH0
mw_struct_mh1 = ratio_mw_mh * MH1
mz_struct_mh1 = 2 * MH1 * (1 + math.pi) / math.sqrt(MU0)

v.check("mu0", MU0, 137.036, rel=3e-6)
v.check("lambda = sin(pi/14)", LAM, 0.22252, rel=5e-6)
v.check("lambda^2", LAM**2, 0.049516, rel=1e-5)
v.check("4 lambda^2 / 5", 4 * LAM**2 / 5, 0.039613, rel=2e-5)
v.check("sin^2 theta_W NLO", sw, 0.23192, rel=2e-4)
v.check("4*pi*(1+pi)", 4 * math.pi * (1 + math.pi), 52.066, rel=2e-5)
v.check("mu0*(1-4lambda^2/5)", MU0 * (1 - 4 * LAM**2 / 5), 131.61, rel=2e-5)
v.check("g_W^2", g2, 0.39563, rel=5e-4)
v.check("g_W", g, 0.62899, rel=3e-4)
v.check("SM g_W from PDG M_W and v", 2 * MW_PDG / V, 0.65287, rel=3e-5)
v.check("g_W deficit percent", 100 * (g - 2 * MW_PDG / V) / (2 * MW_PDG / V), -3.64, rel=2e-2)

v.check("body M_W NLO", mw_nlo, 77.42, rel=5e-4)
v.check("body M_W residual percent", 100 * (mw_nlo - MW_PDG) / MW_PDG, -3.68, rel=5e-3)
v.check(
    "abstract M_W tree value",
    mw_nlo,
    78.742,
    rel=1e-3,
    detail="Expected fail: the body formula gives about 77.42 GeV; 78.742 appears stale.",
)
v.check(
    "abstract M_W residual",
    100 * (mw_nlo - MW_PDG) / MW_PDG,
    -2.03,
    rel=1e-2,
    detail="Expected fail: 77.42 GeV is about -3.68%, not -2.03%.",
)

v2 = V**2
mw2_numerator = math.pi * (1 + math.pi) * v2
mw2_denominator = MU0 * (1 - 4 * LAM**2 / 5)
mw2 = mw2_numerator / mw2_denominator
v.check("v^2", v2, 60624, rel=5e-6)
v.check(
    "explicit M_W^2 numerator",
    mw2_numerator,
    790790,
    rel=5e-4,
    detail="Expected fail: the product is about 788795, not 790790.",
)
v.check("explicit M_W^2 denominator", mw2_denominator, 131.61, rel=2e-5)
v.check(
    "explicit M_W^2 value",
    mw2,
    6009.1,
    rel=5e-4,
    detail="Expected fail: using the stated formula gives about 5993.5.",
)
v.check(
    "explicit M_W from M_W^2",
    math.sqrt(mw2),
    77.52,
    rel=5e-4,
    detail="Expected fail: using the exact formula gives about 77.42.",
)

v.check("structural M_W/m_H ratio", ratio_mw_mh, 0.61632, rel=1e-4)
v.check("structural M_W with mH0", mw_struct_mh0, 75.87, rel=2e-4)
v.check("structural M_W with mH1", mw_struct_mh1, 77.40, rel=6e-4)
v.check("PDG M_W/m_H ratio", MW_PDG / 125.20, 0.64198, rel=2e-5)
v.check("M_W/m_H residual percent", 100 * (ratio_mw_mh - MW_PDG / 125.20) / (MW_PDG / 125.20), -4.00, rel=3e-3)

v.check("cos theta_W", cosw, 0.87644, rel=5e-5)
v.check("body M_Z NLO", mz_nlo, 88.34, rel=1e-4)
v.check("body M_Z residual percent", 100 * (mz_nlo - MZ_PDG) / MZ_PDG, -3.13, rel=2e-3)
v.check(
    "abstract M_Z tree value",
    mz_nlo,
    89.843,
    rel=1e-3,
    detail="Expected fail: the body formula gives about 88.34 GeV; 89.843 appears stale.",
)
v.check(
    "abstract M_Z residual",
    100 * (mz_nlo - MZ_PDG) / MZ_PDG,
    -1.48,
    rel=1e-2,
    detail="Expected fail: 88.34 GeV is about -3.13%, not -1.48%.",
)
v.check("structural M_Z with mH1", mz_struct_mh1, 88.87, rel=6e-4)
v.check("structural M_Z residual percent", 100 * (mz_struct_mh1 - MZ_PDG) / MZ_PDG, -2.55, rel=2e-2)
v.check("M_W/M_Z NLO ratio", cosw, 0.87644, rel=5e-5)
v.check("M_W/M_Z residual percent", 100 * (cosw - MW_PDG / MZ_PDG) / (MW_PDG / MZ_PDG), -0.56, rel=5e-2)

delta_r = 0.0381
mw_after_delta_r = mw_nlo * (1 + delta_r / 2)
v.check("Delta r half-shift percent", 100 * delta_r / 2, 1.90, rel=3e-3)
v.check("M_W after Delta r", mw_after_delta_r, 78.89, rel=2e-4)
v.check("residual after Delta r", 100 * (mw_after_delta_r - MW_PDG) / MW_PDG, -1.85, rel=5e-3)
v.check("alpha_s/pi * 1/3 percent", 100 * (0.118 / math.pi) * (1 / 3), 1.25, rel=3e-3)
mw_after_dr_as = mw_nlo * (1 + 0.0190 + 0.0125)
v.check("M_W after Delta r + alpha_s estimate", mw_after_dr_as, 79.9, rel=2e-3)
v.check("residual after Delta r + alpha_s", 100 * (mw_after_dr_as - MW_PDG) / MW_PDG, -0.60, rel=8e-2)

listed_correction_sum = 1.47 + 1.00 + 0.38
v.check("listed correction sum", listed_correction_sum, 2.94, rel=1e-2)
v.check(
    "TOE plus listed corrections",
    77.42 + listed_correction_sum,
    80.36,
    abs_tol=0.03,
    detail="Expected fail: the listed correction rows sum to 2.85 GeV, giving 80.27 GeV.",
)
v.check("total correction needed", MW_PDG - 77.42, 2.94, rel=6e-3)

sys.exit(v.summary())
