"""Inspect Binaryen 129 folded WAT; count static instructions, not executions.

This file also owns the definition of a SIMD instruction: attribute.py loads it
so the per-function counts and the whole-module counts use one pattern.
"""
import hashlib
import json
from collections import Counter
from pathlib import Path
import re
import sys

# Instruction heads only, such as `(v128.load` or `(i32x4.add`. A bare `v128`
# type tag in a local declaration is not preceded by `(` and a family prefix.
SIMD_OPCODE = re.compile(
    r"\(((?:v128|i8x16|i16x8|i32x4|i64x2|f32x4|f64x2)\.[a-z0-9_]+)"
)


def count_simd(wat):
    """Static SIMD opcode occurrences in folded WAT text, keyed by opcode."""
    return Counter(SIMD_OPCODE.findall(wat))


def main(root):
    rows = []
    for variant in ["scalar", "simd"]:
        for crate in ["downsample", "aggregate"]:
            binary = (root / variant / f"vizcrush_{crate}_bg.wasm").read_bytes()
            ops = count_simd((root / variant / f"{crate}.wat").read_text())
            rows.append({"variant": variant, "crate": crate, "bytes": len(binary),
                         "sha256": hashlib.sha256(binary).hexdigest(),
                         "simdInstructionCount": sum(ops.values()), "opcodes": dict(sorted(ops.items()))})
    print(json.dumps(rows, indent=2))


if __name__ == "__main__":
    main(Path(sys.argv[1]))
