#!/usr/bin/env python3
"""Read-only integrity verification for the frozen Apeiron v7.13 package.

This script never imports or executes a solver module and never evaluates the
physical fixed-point map. It verifies hashes, stored identities, array
structure, registered inequalities, and the recorded Float64 crossing rule.
"""

from __future__ import annotations

import hashlib
import json
import math
import sys
from decimal import Decimal, localcontext
from pathlib import Path

import numpy as np


ROOT = Path(__file__).resolve().parent
MANIFEST = ROOT / "APEIRON_REPRODUCIBILITY_MANIFEST_LATEST.json"
GATE_SPEC = ROOT / "APEIRON_V7_13_GATE_SPECIFICATION_LATEST.json"


def fail(message: str) -> None:
    raise RuntimeError(message)


def sha256(path: Path) -> str:
    digest = hashlib.sha256()
    with path.open("rb") as stream:
        for chunk in iter(lambda: stream.read(1024 * 1024), b""):
            digest.update(chunk)
    return digest.hexdigest()


def load_json(path: Path) -> dict:
    with path.open("r", encoding="utf-8") as stream:
        return json.load(stream)


def verify_hashes(manifest: dict) -> None:
    for item in manifest["files"]:
        path = ROOT / item["path"]
        if not path.is_file():
            fail(f"missing:{item['path']}")
        observed = sha256(path)
        if observed != item["sha256"]:
            fail(f"sha256:{item['path']}:{observed}")


def compare_gate(observed, operator: str, threshold) -> bool:
    if operator == "<":
        return float(observed) < float(threshold)
    if operator == ">":
        return float(observed) > float(threshold)
    if operator == "is":
        return observed is threshold
    fail(f"unknown_operator:{operator}")
    return False


def verify_v713(manifest: dict, gate_spec: dict) -> None:
    source = ROOT / "TECHNICAL_SOURCES"
    protocol = load_json(source / "RECOVERY_PROTOCOL_v7_13.json")
    register = load_json(source / "RECOVERY_GATE_REGISTER_v7_13_STAGE00.json")
    result = load_json(source / "STAGE00_HARD_PASS_RESULT_v7_13.json")
    crossing = load_json(source / "CROSSING_RESOLUTION_RESULT_v7_13.json")
    master = load_json(source / "STATE_SNAPSHOT/MASTER_RECOVERY_STATE_LATEST.json")
    meta = load_json(source / "STATE_SNAPSHOT/CURRENT_META_LATEST.json")

    expected = manifest["expected"]["v7_13"]
    if register["classification"] != expected["classification"]:
        fail("v7.13:classification")
    if not result["hard_gate_pass"] or result["iterations"] != []:
        fail("v7.13:terminal_record")
    if register["newton_steps"] != expected["newton_steps"]:
        fail("v7.13:newton_steps")
    if result["function_evaluations"] != 1 or meta["function_evaluations"] != 1:
        fail("v7.13:function_evaluations")
    if register["finalization_failure"] is not None:
        fail("v7.13:finalization_failure")
    if not math.isclose(
        float(protocol["stage0_tau"]),
        expected["tau_binary64"],
        rel_tol=0.0,
        abs_tol=0.0,
    ):
        fail("v7.13:protocol_tau")
    if float(master["tau"]) != expected["tau_binary64"]:
        fail("v7.13:master_tau")

    with np.load(source / "STAGE00_HARD_PASS_SOLUTION_v7_13.npz", allow_pickle=False) as data:
        if set(data.files) != {"t", "y", "x", "tau"}:
            fail("v7.13:solution_keys")
        if list(data["t"].shape) != expected["solution_shape_t"]:
            fail("v7.13:t_shape")
        if list(data["y"].shape) != expected["solution_shape_y"]:
            fail("v7.13:y_shape")
        if list(data["x"].shape) != expected["solution_shape_x"]:
            fail("v7.13:x_shape")
        if any(data[key].dtype != np.float64 for key in ("t", "y", "x", "tau")):
            fail("v7.13:dtype")
        if float(data["tau"]) != expected["tau_binary64"]:
            fail("v7.13:solution_tau")

    with np.load(source / "STATE_SNAPSHOT/CURRENT_STATE_LATEST.npz", allow_pickle=False) as state:
        if set(state.files) != {"x", "delta", "newton", "cycle", "phase", "rb"}:
            fail("v7.13:state_keys")
        if state["x"].shape != (92166,) or state["rb"].shape != (92166,):
            fail("v7.13:state_shape")
        if int(state["newton"]) != 1 or int(state["cycle"]) != 0:
            fail("v7.13:state_index")
        if str(state["phase"]) != "gmres":
            fail("v7.13:state_phase")

    if protocol["strict_gates"] != register["strict_gates"]:
        fail("v7.13:protocol_register_threshold_mismatch")

    for name, gate in gate_spec["gates"].items():
        passed = compare_gate(gate["observed"], gate["operator"], gate["threshold"])
        if passed is not bool(gate["passed"]):
            fail(f"v7.13:gate:{name}")

    if not all(register["gates"].values()):
        fail("v7.13:registered_gate_boolean")
    if crossing["status"] != "schedule_complete_float64_resolution":
        fail("crossing:status")


def verify_v674(manifest: dict) -> None:
    source = ROOT / "TECHNICAL_SOURCES"
    result = load_json(source / "STAGE00_NONPASS_RESULT_v6_74.json")
    register = load_json(source / "RECOVERY_GATE_REGISTER_v6_74_STAGE00.json")
    expected = manifest["expected"]["v6_74"]
    if register["classification"] != expected["classification"]:
        fail("v6.74:classification")
    if result["hard_gate_pass"] or register["hard_gate_pass"]:
        fail("v6.74:hard_gate_pass")
    if register["failed_gates"] != expected["failed_gates"]:
        fail("v6.74:failed_gates")
    if float(register["tau"]) != expected["tau_binary64"]:
        fail("v6.74:tau")
    with np.load(source / "STAGE00_NONPASS_SOLUTION_v6_74.npz", allow_pickle=False) as data:
        if float(data["tau"]) != expected["tau_binary64"]:
            fail("v6.74:solution_tau")


def verify_crossing(manifest: dict) -> None:
    source = ROOT / "TECHNICAL_SOURCES"
    crossing = load_json(source / "CROSSING_RESOLUTION_RESULT_v7_13.json")
    hp = float(crossing["latest_hard_pass"]["tau_binary"])
    npass = float(crossing["immutable_nonpass"]["tau_binary"])
    if math.nextafter(hp, math.inf) != npass:
        fail("crossing:not_adjacent_binary64")
    with localcontext() as context:
        context.prec = 80
        protocol_hp = Decimal(crossing["latest_hard_pass"]["tau_exact_protocol"])
        protocol_npass = Decimal(crossing["immutable_nonpass"]["tau_exact"])
        exact_midpoint = (protocol_hp + protocol_npass) / Decimal(2)
    if exact_midpoint != Decimal(crossing["next_exact_midpoint"]):
        fail("crossing:exact_midpoint")
    if float(exact_midpoint) != float(crossing["next_midpoint_binary"]):
        fail("crossing:protocol_midpoint_rounding")
    expected = manifest["expected"]["crossing"]
    if bool(crossing["binary_endpoints_adjacent"]) is not expected["binary_endpoints_adjacent"]:
        fail("crossing:recorded_adjacency")
    if bool(crossing["next_midpoint_equals_nonpass_binary"]) is not expected["next_midpoint_equals_nonpass_binary"]:
        fail("crossing:recorded_midpoint")
    if not bool(crossing["further_float64_bisection_forbidden"]):
        fail("crossing:completion_rule")


def main() -> int:
    manifest = load_json(MANIFEST)
    gate_spec = load_json(GATE_SPEC)
    if manifest["solver_execution_permitted"] is not False:
        fail("manifest:solver_permission")
    verify_hashes(manifest)
    verify_v713(manifest, gate_spec)
    verify_v674(manifest)
    verify_crossing(manifest)
    print("APEIRON_PUBLICATION_PACKAGE_VERIFY_PASS")
    return 0


if __name__ == "__main__":
    try:
        sys.exit(main())
    except Exception as exc:
        print(f"APEIRON_PUBLICATION_PACKAGE_VERIFY_FAIL:{exc}", file=sys.stderr)
        sys.exit(1)
