#!/usr/bin/env python3
"""Measure Inclusive Sans upstream fonts and freeze the overlay build spec.

The tabular slot is shared across upright AND italic so tables align across
styles: slot(master) = max advance of any supported digit or currency in
either style at that master. Writes pipeline/spec.json. Read-only against
upstream/.
"""
import json
from pathlib import Path

from fontTools.ttLib import TTFont
from fontTools.varLib.instancer import instantiateVariableFont

ROOT = Path(__file__).resolve().parent.parent
UPSTREAM = ROOT / "upstream"
SPEC = ROOT / "pipeline" / "spec.json"

FONTS = {
    "upright": UPSTREAM / "InclusiveSans-VariableFont_wght.ttf",
    "italic": UPSTREAM / "InclusiveSans-Italic-VariableFont_wght.ttf",
}
DIGITS = [
    "zero",
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven",
    "eight",
    "nine",
]
CURRENCIES = {
    "dollar": "U+0024",
    "sterling": "U+00A3",
    "yen": "U+00A5",
    "uni20B9": "U+20B9",
    "Euro": "U+20AC",
}
TABULAR_BASES = DIGITS + list(CURRENCIES)
MATH_BASES = [
    "equal",
    "slash",
    "less",
    "greater",
    "minus",
    "asciitilde",
    "percent",
    "degree",
]
MATH_COMPOSITES = {
    "notequal": "U+2260",
    "lessequal": "U+2264",
    "greaterequal": "U+2265",
    "approxequal": "U+2248",
    "perthousand": "U+2030",
}
SS02_L_SOURCES = {
    "l": "U+006C",
    "lacute": "U+013A",
    "uni013C": "U+013C",
    "uni013C.loclMAH": "U+013C (locl MAH)",
    "lcaron": "U+013E",
    "ldot": "U+0140",
    "lslash": "U+0142",
    "uni1E37": "U+1E37",
    "uni1E3B": "U+1E3B",
}
WEIGHTS = [300, 400, 500, 600, 700]  # 500/600 interpolated; masters are 300/400/700
STATIC_PINS = [450, 550]
FORK_VERSION = "1.200"
RELEASE_DATE = "2026-07-29"
WINDOWS_ASCENT = 1159


def advances(path: Path, wght: int, glyphs: list[str]) -> dict:
    inst = instantiateVariableFont(TTFont(path), {"wght": wght})
    hmtx = inst["hmtx"]
    return {glyph: hmtx[glyph][0] for glyph in glyphs}


def main() -> None:
    per_style = {
        style: {
            weight: advances(path, weight, TABULAR_BASES) for weight in WEIGHTS
        }
        for style, path in FONTS.items()
    }
    math_advances = {
        style: {
            weight: advances(path, weight, MATH_BASES) for weight in WEIGHTS
        }
        for style, path in FONTS.items()
    }

    slot = {}
    for w in WEIGHTS:
        slot[w] = max(
            per_style[style][w][glyph]
            for style in per_style
            for glyph in TABULAR_BASES
        )

    spec = {
        "source": "Inclusive Sans 2.004 (OFL 1.1, no Reserved Font Name)",
        "fork": "Pivot Sans",
        "fork_version": FORK_VERSION,
        "release_date": RELEASE_DATE,
        "windows_ascent": WINDOWS_ASCENT,
        "weights": WEIGHTS,
        "masters": [300, 400, 700],
        "digits": DIGITS,
        "currencies": CURRENCIES,
        "tabular_bases": TABULAR_BASES,
        "math_composites": MATH_COMPOSITES,
        "ss02_l_sources": SS02_L_SOURCES,
        "static_pins": STATIC_PINS,
        "advances": per_style,
        "math_advances": math_advances,
        "tabular_slot": slot,
        "notes": [
            "money slot is uniform per master across digits, $ £ ¥ ₹ €, upright, and italic",
            "tabular composites are centered: offset(w) = round((slot(w) - adv(w)) / 2)",
            "intermediate weights (500/600) inherit via linear variation",
            "relation composites use the equal-sign advance; perthousand derives from percent plus the unslashed degree circle because the full-size zero is slashed",
            "ss02 maps eight encoded lowercase-l forms plus the Marshallese localized U+013C form to flattened native-source component recipes and one shared weight-varying foot; default glyphs and metrics remain unchanged",
        ],
    }
    SPEC.write_text(json.dumps(spec, indent=2) + "\n")

    for s in per_style:
        row = lambda w: " ".join(
            f"{per_style[s][w][glyph]:>4}" for glyph in TABULAR_BASES
        )
        print(f"[{s}]")
        for w in WEIGHTS:
            print(f"  {w}: {row(w)}  slot={slot[w]}")
    print(f"\nwrote {SPEC}")


if __name__ == "__main__":
    main()
