#!/usr/bin/env python3
"""Verify the immutable, locally stored V2 runtime-bytecode snapshot.

This check is intentionally offline. It does not call an RPC endpoint and it
does not rebuild V2 source. The checked-in reports are the frozen observation
set; the manifest makes drift in those observations reviewable.
"""
from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import Any

ROOT = Path(__file__).resolve().parents[1]
PRIMARY = ROOT / "baseline/onchain_fetch_report.json"
RETRY = ROOT / "baseline/onchain_retry_report.json"
MANIFEST = ROOT / "ci/manifests/v2-bytecode-manifest.json"


def _key(record: dict[str, Any]) -> tuple[str, str]:
    return record["chain"], record["address"].lower()


def _records() -> list[dict[str, Any]]:
    primary = json.loads(PRIMARY.read_text())["results"]
    retry = {_key(item): item for item in json.loads(RETRY.read_text())["results"]}
    records: list[dict[str, Any]] = []

    for item in primary:
        retry_item = retry.get(_key(item))
        digest = item.get("bytecode_sha256") or (retry_item or {}).get("sha256")
        byte_count = item.get("bytecode_bytes") or (retry_item or {}).get("bytes")
        if not digest or byte_count is None:
            raise SystemExit(
                "incomplete frozen V2 bytecode observation: "
                f"{item['chain']} {item['name']} {item['address']}"
            )
        records.append(
            {
                "chain": item["chain"],
                "name": item["name"],
                "address": item["address"].lower(),
                "runtimeBytecodeBytes": byte_count,
                "runtimeBytecodeSha256": digest,
            }
        )

    if len({_key(record) for record in records}) != len(records):
        raise SystemExit("duplicate chain/address in frozen V2 bytecode observations")
    return sorted(records, key=lambda item: (item["chain"], item["name"], item["address"]))


def _manifest() -> dict[str, Any]:
    records = _records()
    return {
        "schemaVersion": 1,
        "scope": "Frozen V2 deployed runtime bytecode observations; V2 source is not rebuilt.",
        "hash": "sha256",
        "recordCount": len(records),
        "records": records,
    }


def _write_json(path: Path, payload: dict[str, Any]) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n")


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("--write", action="store_true", help="refresh the checked-in manifest")
    args = parser.parse_args()
    actual = _manifest()

    if args.write:
        _write_json(MANIFEST, actual)
        print(f"wrote {MANIFEST.relative_to(ROOT)} ({actual['recordCount']} V2 runtime bytecode hashes)")
        return

    expected = json.loads(MANIFEST.read_text())
    if expected != actual:
        raise SystemExit(
            "frozen V2 bytecode manifest drift; inspect the pinned reports and run "
            "ci/check_v2_bytecode_manifest.py --write only for an approved snapshot refresh"
        )
    print(f"verified {actual['recordCount']} frozen V2 runtime bytecode hashes")


if __name__ == "__main__":
    main()
