#!/usr/bin/env python3
"""Precompute mpmath O3 vectors for engineering.uncertainty.type_b_nu.

GUM G.4.2: ν = ½ (u/σ(u))². σ(u)=0 → infinite. Not Type B u_B, not Welch, not U=k·u_c.
80 dps, round-to-nearest binary64.

Re-run: python3 scripts/lib/cvp/oracles/generate-type-b-nu-o3.py
"""
from __future__ import annotations

import json
import math
import shutil
from pathlib import Path

import mpmath as mp

DPS = 80
GENERATOR_ID = "type-b-nu-mpmath-o3"
GENERATOR_VERSION = "1.0.0"
SEED = "20260916.type-b-nu-o3"


def f64(x: mp.mpf) -> float:
    return float(x)


def nu_row(u, sigma_u) -> dict:
    u = mp.mpf(u)
    su = mp.mpf(sigma_u)
    rel = su / u
    if rel == 0:
        return {
            "infinite": True,
            "rel_f64": 0.0,
            "rel_decimal": "0",
            "u_f64": f64(u),
            "sigma_u_f64": 0.0,
        }
    nu = mp.mpf("0.5") / (rel * rel)
    return {
        "infinite": False,
        "nu_f64": f64(nu),
        "nu_decimal": mp.nstr(nu, 40, strip_zeros=False),
        "rel_f64": f64(rel),
        "rel_decimal": mp.nstr(rel, 40, strip_zeros=False),
        "u_f64": f64(u),
        "sigma_u_f64": f64(su),
    }


def row(vid: str, inputs: dict, extra: dict, *, kind: str) -> dict:
    return {"id": vid, "kind": kind, "inputs": inputs, **extra}


def vectors() -> list[dict]:
    return [
        row("o3-gum25", {"u": 2, "sigma_u": 0.5}, nu_row(2, "0.5"), kind="finite"),
        row("o3-inf", {"u": 1, "sigma_u": 0}, nu_row(1, 0), kind="infinite"),
        row("o3-10pct", {"u": 1, "sigma_u": 0.1}, nu_row(1, "0.1"), kind="finite"),
        row("o3-alias", {"u_B": 2, "su": 0.5}, nu_row(2, "0.5"), kind="alias"),
        row("o3-scale", {"u": 4, "sigma_u": 1}, nu_row(4, 1), kind="finite"),
        row("o3-half", {"u": 2, "sigma_u": 1}, nu_row(2, 1), kind="finite"),
        row("o3-ui", {"u_i": 2, "delta_u": 0.5}, nu_row(2, "0.5"), kind="alias"),
        row("o3-tight", {"u": 10, "sigma_u": 0.05}, nu_row(10, "0.05"), kind="finite"),
    ]


def main() -> None:
    mp.mp.dps = DPS
    here = Path(__file__).resolve().parent
    table = {
        "family": "type_b_nu",
        "generator_id": GENERATOR_ID,
        "generator_version": GENERATOR_VERSION,
        "seed": SEED,
        "mpmath_dps": DPS,
        "precision_bits": int(DPS * math.log2(10)),
        "library": f"mpmath {mp.__version__}",
        "notes": "GUM G.4.2 ν only. Independent of Node Math and the IUT. Welch and U=k·u_c are not tabulated.",
        "vectors": vectors(),
    }
    dest = here / "type-b-nu-o3-tables.json"
    dest.write_text(json.dumps(table, indent=2) + "\n", encoding="utf-8")
    public = here.parents[3] / "public/developers/cvp/reproduce"
    public.mkdir(parents=True, exist_ok=True)
    shutil.copy2(dest, public / "type-b-nu-o3-tables.json")
    shutil.copy2(Path(__file__), public / "generate-type-b-nu-o3.py")
    print(f"wrote {dest} ({len(table['vectors'])} vectors)")


if __name__ == "__main__":
    main()
