#!/usr/bin/env python3
"""mpmath O3 for mechanical.statics.transverse_shear."""
from __future__ import annotations
import json, math, shutil
from pathlib import Path
import mpmath as mp

def pick(inputs, *keys):
    for key in keys:
        if key in inputs and inputs[key] not in (None, ""):
            return mp.mpf(str(inputs[key]))
    return None


def compute(inputs):
    V = pick(inputs, "V", "shear")
    Q = pick(inputs, "Q", "first_moment", "statical_moment")
    I = pick(inputs, "I", "Ix")
    b = pick(inputs, "b", "t", "thickness")
    tau = (V * Q) / (I * b)
    return {"tau": tau, "V": V, "Q": Q, "I": I, "b": b}


def row(vid, inputs, kind):
    out = compute(inputs)
    packed = {"id": vid, "kind": kind, "inputs": inputs}
    for k, v in out.items():
        if isinstance(v, str):
            packed[k] = v
        else:
            packed[f"{k}_f64"] = float(v)
            packed[f"{k}_decimal"] = mp.nstr(v, 40, strip_zeros=False)
    return packed

def main():
    mp.mp.dps = 80
    here = Path(__file__).resolve().parent
    vectors = [
        row("o3-unit", {"V": "12", "Q": "4", "I": "8", "b": "2"}, "unit"),
        row("o3-alias", {"shear": "24", "first_moment": "6", "Ix": "10", "t": "3"}, "alias"),
        row("o3-awkward", {"V": "13.7", "Q": "2.5", "I": "7.2", "b": "1.8"}, "awkward"),
        row("o3-neg", {"V": "-12", "Q": "4", "I": "8", "b": "2"}, "signed"),
        row("o3-statical", {"V": "50", "statical_moment": "0.01", "I": "0.002", "b": "0.05"}, "statical"),
        row("o3-small", {"V": "1", "Q": "0.1", "I": "0.2", "b": "0.5"}, "small"),
        row("o3-large", {"V": "1e5", "Q": "0.02", "I": "0.01", "b": "0.1"}, "large"),
        row("o3-thickness", {"V": "30", "Q": "5", "I": "15", "thickness": "2"}, "thickness"),
    ]
    table = {
        "family": "transverse_shear",
        "generator_id": "transverse-shear-mpmath-o3",
        "generator_version": "1.0.0",
        "seed": "20260927.transverse-shear-o3",
        "mpmath_dps": 80,
        "precision_bits": int(80 * math.log2(10)),
        "library": f"mpmath {mp.__version__}",
        "notes": "τ = VQ/(I b) (Jourawski); + O3 mpmath tabulated τ.",
        "vectors": vectors,
    }
    dest = here / "transverse-shear-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 / "transverse-shear-o3-tables.json")
    shutil.copy2(Path(__file__), public / "generate-transverse-shear-o3.py")
    print(f"wrote {dest} ({len(vectors)} vectors)")

if __name__ == "__main__":
    main()
