"""Reproduce the New Eruditions public-release comparison.
Standard library only. Run: python calculations.py
This verifies arithmetic, not either analyst's proprietary model.
"""
from decimal import Decimal, getcontext
from datetime import date
from pathlib import Path
import json
import csv

getcontext().prec = 28
D = Decimal
S = D("119.1")  # S1 Q4 2025 body, billion dollars
O = D("110.9")  # S2 Q4 2025, US$ billion
sy_prior = D("90.6")  # S8 original Q4 2024 release, older vintage
aws_million = D("35579")  # S9 company segment disclosure, millions
rows = []

def add(cid, name, formula, inputs, result, assumption, display, status="DERIVED"):
    rows.append(dict(id=cid, name=name, formula=formula, source_inputs=inputs,
                     result=str(result), assumption=assumption, display=display, status=status))
    return result

common = "Use printed body values; treat S1 $ as USD. Rounded estimates, not exact census values."
gap = add("C01", "Printed-total gap", "S - O", "S1:119.1; S2:110.9", S-O, common, "$8.2bn")
pct_o = add("C02", "Gap relative to Omdia", "(S-O)/O*100", "C01; S2:110.9", gap/O*100, common, "about 7.4%")
pct_s = add("C03", "Gap relative to Synergy", "(S-O)/S*100", "C01; S1:119.1", gap/S*100, common, "about 6.9%")
sym = add("C04", "Symmetric percentage difference", "(S-O)/((S+O)/2)*100", "S1; S2", gap/((S+O)/2)*100, "Mean is an arithmetic denominator, not a best estimate.", "about 7.1%")

rounding = "Sensitivity only: assume nearest $0.1bn rounding, independently; actual rounding rules undisclosed. Bounds are not confidence intervals."
low_s, high_s = S-D(".05"), S+D(".05")
low_o, high_o = O-D(".05"), O+D(".05")
add("C05a", "Gap lower rounding bound", "(S-.05)-(O+.05)", "S1; S2", low_s-high_o, rounding, "$8.1bn boundary", "SENSITIVITY")
add("C05b", "Gap upper rounding bound", "(S+.05)-(O-.05)", "S1; S2", high_s-low_o, rounding, "$8.3bn boundary", "SENSITIVITY")
add("C06", "Omdia conditional prior-year level", "O/(1+.29)", "S2:110.9;29%", O/D("1.29"),
    "29% assumed exact and same currency/coverage/vintage basis as level. Omdia does not disclose full FX policy.", "about $86.0bn", "CONDITIONAL")
growth_rounding = "Assume nearest $0.1bn and nearest whole percentage-point growth, plus same-basis growth. Sensitivity, not source observation."
add("C07a", "Omdia implied prior lower bound", "(O-.05)/(1+.295)", "S2", low_o/D("1.295"), growth_rounding, "about $85.6bn", "CONDITIONAL")
add("C07b", "Omdia implied prior upper bound", "(O+.05)/(1+.285)", "S2", high_o/D("1.285"), growth_rounding, "about $86.3bn", "CONDITIONAL")
add("C08", "Rejected Synergy reverse-growth calculation", "S/(1+.30)", "S1:119.1;30%", S/D("1.30"),
    "NOT a valid nominal Q4 2024 estimate: S1 30% backs out FX effects and no level bridge is published.", "$91.6bn mechanically, rejected as baseline", "REJECTED INFERENCE")
add("C09", "Synergy rough prior from printed dollar increment", "S-29", "S1:119.1;29bn increase", S-D("29"),
    "Treat rounded $29bn increment as central value. Not an exact baseline or confirmed revision.", "about $90.1bn", "CONDITIONAL")
add("C10", "Change between Synergy release vintages", "(S/90.6-1)*100", "S1:119.1; S8:90.6", (S/sy_prior-1)*100,
    "Older printed baseline. Cross-vintage dollar arithmetic; not source-reported 2026 FX-adjusted growth.", "about 31.5%", "CROSS-VINTAGE")
add("C11", "Dollar change across release vintages", "S-90.6", "S1; S8", S-sy_prior,
    "Older printed baseline; discrepancy with rounded $29bn is not proof of revision.", "$28.5bn", "CROSS-VINTAGE")
add("C12", "Annual average quarter, not Q4", "419/4", "S1 full-year:419", D("419")/4,
    "Arithmetic average of four quarters, not a substitute for observed Q4.", "about $104.8bn", "ILLUSTRATION")
add("C13", "Q4 annualized scale, not full-year revenue", "S*4", "S1:119.1", S*4,
    "Assume Q4 pace repeated for four quarters; not a forecast or observed annual total.", "$476.4bn annualized", "ILLUSTRATION")

shares = {"Amazon": (D("28"), D("32")), "Microsoft": (D("21"), D("22")), "Google": (D("14"), D("12"))}
vendor_ranges = {}
for idx, (vendor, (ss, os)) in enumerate(shares.items(), start=14):
    for tag, total, sh, low, high in [("S", S, ss, low_s, high_s), ("O", O, os, low_o, high_o)]:
        implied = total*sh/100
        add(f"C{idx}{tag}", f"{vendor}: implied {tag} eligible amount", "total*share/100",
            f"{'S1' if tag=='S' else 'S2'}:{total};share:{sh}%", implied,
            "Rounded share applied to its own full-market total; inferred eligible amount, not disclosed company revenue.",
            f"about ${implied.quantize(D('.1'))}bn")
        lo = low*(sh-D(".5"))/100
        hi = high*(sh+D(".5"))/100
        vendor_ranges[(vendor,tag)] = (lo,hi)
        for edge, value in [("low",lo),("high",hi)]:
            add(f"C{idx}{tag}-{edge}", f"{vendor}: {tag} rounding {edge}",
                "(total +/- .05)*(share +/- .5)/100",
                f"{'S1' if tag=='S' else 'S2'}", value,
                rounding+" Also assume nearest whole percent share rounding.",
                f"${value.quantize(D('.01'))}bn boundary", "SENSITIVITY")
    predicted = O*os/S
    add(f"C{idx}P", f"{vendor}: Synergy share if Omdia numerator unchanged",
        "O*O_share/S", f"S1 total; S2 total and {vendor} share", predicted,
        "Counterfactual: all vendor numerator values unchanged; only denominator differs. Not actual normalized share.",
        f"about {predicted.quantize(D('.1'))}%", "COUNTERFACTUAL")

aws = add("C17", "AWS company segment unit normalization", "35579/1000", "S9:35579 million", aws_million/1000,
          "Company segment total; scope equivalence to analyst numerator not established.", "$35.579bn")
add("C18S", "AWS segment minus Synergy implied amount", "35.579-119.1*.28", "S9; S1", aws-S*D(".28"),
    "Scope diagnostic only; cannot label difference omitted AWS revenue or estimation error.", "about $2.2bn", "DIAGNOSTIC")
add("C18O", "AWS segment minus Omdia implied amount", "35.579-110.9*.32", "S9; S2", aws-O*D(".32"),
    "Near match after rounding is not proof Omdia uses full AWS segment revenue.", "about $0.1bn", "DIAGNOSTIC")
add("C19S", "Sum of Synergy full-market top-three shares", "28+21+14", "S1 shares", D("28")+D("21")+D("14"),
    "Sum of rounded shares; S1 separately says 68% in public IaaS/PaaS submarket.", "about 63%")
add("C19O", "Sum of Omdia full-market top-three shares", "32+22+12", "S2 shares; S17 chart", D("32")+D("22")+D("12"),
    "Sum of rounded shares; consistent with S17.", "about 66%")
add("C20", "Publication-date interval", "2026-03-26 minus 2026-02-05", "S1; S2", D((date(2026,3,26)-date(2026,2,5)).days),
    "49 elapsed days; no inference about causal revisions or missing earnings.", "49 days")

# Arithmetic consistency and counterfactual checks; these do not validate analyst models.
assert gap == D("8.2")
assert S*D(".28") == D("33.348")
assert O*D(".32") == D("35.488")
assert S*D(".14") == D("16.674")
assert O*D(".12") == D("13.308")
assert aws == D("35.579")
assert vendor_ranges[("Amazon","S")][1] < vendor_ranges[("Amazon","O")][0]
assert vendor_ranges[("Google","O")][1] < vendor_ranges[("Google","S")][0]
assert low_s-high_o > 0
assert len({r["id"] for r in rows}) == len(rows)

if __name__ == "__main__":
    output = Path(__file__).resolve().parent if "__file__" in globals() else Path.cwd()
    (output/"calculation-results.json").write_text(json.dumps(rows,indent=2), encoding="utf-8")
    with (output/"calculation-results.csv").open("w",newline="",encoding="utf-8-sig") as f:
        writer=csv.DictWriter(f, fieldnames=list(rows[0]))
        writer.writeheader()
        writer.writerows(rows)
    for row in rows:
        print(row["id"]+" | "+row["name"]+" | "+row["display"]+" | "+row["status"])
    print(f"Verified {len(rows)} calculation records; wrote JSON and CSV.")
