#!/usr/bin/env python3
"""Build production V3 contracts and enforce a 2 KiB EIP-170 safety margin."""
from __future__ import annotations

import json
import shutil
import subprocess
import tempfile
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
V3 = ROOT / "v3-src"
EIP170_LIMIT = 24_576
REQUIRED_MARGIN = 2_048
MAX_RUNTIME = EIP170_LIMIT - REQUIRED_MARGIN


def main() -> None:
    forge = shutil.which("forge")
    if not forge:
        raise SystemExit("Forge is required for the V3 runtime-size gate")
    with tempfile.TemporaryDirectory(prefix="vaultfire-v3-size-") as directory:
        out = Path(directory) / "out"
        subprocess.run(
            [
                forge,
                "build",
                "--root",
                str(V3),
                "--force",
                "--use",
                "0.8.24",
                "--out",
                str(out),
                "--cache-path",
                str(Path(directory) / "cache"),
                "--skip",
                "test",
                "--skip",
                "script",
            ],
            check=True,
        )
        oversized: list[str] = []
        measured: list[tuple[str, int]] = []
        for artifact in sorted(out.rglob("*.json")):
            if "build-info" in artifact.parts:
                continue
            data = json.loads(artifact.read_text())
            runtime = ((data.get("deployedBytecode") or {}).get("object") or "").removeprefix("0x")
            if not runtime or "__" in runtime:
                continue
            size = len(bytes.fromhex(runtime))
            if size <= 17:  # interfaces and link-only libraries
                continue
            measured.append((data.get("contractName", artifact.stem), size))
            if size > MAX_RUNTIME:
                oversized.append(f"{measured[-1][0]}={size}B (margin {EIP170_LIMIT-size}B)")
        if oversized:
            raise SystemExit(
                f"V3 runtime exceeds {MAX_RUNTIME}B policy ceiling: " + ", ".join(oversized)
            )
        print(
            f"verified {len(measured)} deployable V3 runtimes <= {MAX_RUNTIME} bytes "
            f"({REQUIRED_MARGIN}-byte EIP-170 margin)"
        )


if __name__ == "__main__":
    main()
