import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]  # if make_row19_tex.py is in tools/
IN_JSON = ROOT / "results" / "row19_results.json"
OUT_TEX = ROOT / "results" / "row19_results.tex"

_LATEX_ESC = {
    "\\": r"\textbackslash{}",
    "{": r"\{",
    "}": r"\}",
    "#": r"\#",
    "$": r"\$",
    "%": r"\%",
    "&": r"\&",
    "_": r"\_",
    "^": r"\^{}",
    "~": r"\~{}",
}

def latex_escape(s: str) -> str:
    # Escape LaTeX special characters in text-mode macro bodies.
    # This makes results/row19_results.tex always safe to \input.
    return "".join(_LATEX_ESC.get(ch, ch) for ch in s)

def fmt(x):
    if x is None:
        return "--"
    if isinstance(x, bool):
        return "true" if x else "false"
    if isinstance(x, float):
        return f"{x:.6g}"
    if isinstance(x, int):
        return str(x)
    if isinstance(x, (list, tuple)):
        return "[" + ", ".join(fmt(v) for v in x) + "]"
    return str(x)

def emit_macro(name: str, value) -> str:
    # Always escape since macros are printed in text contexts (tables/boxes).
    return f"\\newcommand{{\\{name}}}{{{latex_escape(fmt(value))}}}\n"

def main():
    data = json.loads(IN_JSON.read_text(encoding="utf-8"))

    frg  = data.get("frg", {}) or {}
    pos  = data.get("positivity", {}) or {}
    pg   = data.get("ppn_gw", {}) or {}
    jac  = data.get("jacobian", {}) or {}
    scan = data.get("scan_summary", {}) or {}

    out = []
    out.append("% Auto-generated. DO NOT EDIT BY HAND.\n")

    out.append(emit_macro("RowXIXVerdict", data.get("verdict", "PENDING")))
    out.append(emit_macro("RowXIXNscan", scan.get("n_points")))

    out.append(emit_macro("RowXIXFPfound", frg.get("fixed_point_found")))
    out.append(emit_macro("RowXIXgstar", frg.get("gstar")))
    out.append(emit_macro("RowXIXlstar", frg.get("lambdastar")))
    out.append(emit_macro("RowXIXthetas", frg.get("critical_exponents")))

    out.append(emit_macro("RowXIXPosNonEmpty", pos.get("region_nonempty")))
    out.append(emit_macro("RowXIXPosMargin", pos.get("min_margin")))

    out.append(emit_macro("RowXIXPPNok", pg.get("ppn_ok")))
    out.append(emit_macro("RowXIXGWok", pg.get("gw_speed_ok")))

    out.append(emit_macro("RowXIXJacOK", jac.get("analytic_numeric_agree")))
    out.append(emit_macro("RowXIXJacErr", jac.get("max_rel_err")))

    OUT_TEX.parent.mkdir(parents=True, exist_ok=True)
    OUT_TEX.write_text("".join(out), encoding="utf-8")
    print(f"Wrote {OUT_TEX}")

if __name__ == "__main__":
    main()