#!/usr/bin/env python3
"""Verify the committed bit-flip results without downloading the model or dataset."""

from __future__ import annotations

import csv
import hashlib
import json
from pathlib import Path


ROOT = Path(__file__).resolve().parent
OUTPUTS = ROOT / "outputs"
EXPECTED_CANDIDATES = 640 * (32 + 16 + 8)


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


def main() -> int:
    manifest = json.loads((OUTPUTS / "manifest.json").read_text(encoding="utf-8"))
    results = json.loads((OUTPUTS / "results.json").read_text(encoding="utf-8"))

    for filename, expected in manifest["files"].items():
        path = OUTPUTS / filename
        assert path.exists(), f"missing output: {filename}"
        assert path.stat().st_size == expected["bytes"], f"size mismatch: {filename}"
        assert sha256_file(path) == expected["sha256"], f"hash mismatch: {filename}"

    with (OUTPUTS / "candidate-search.csv").open(newline="", encoding="utf-8") as handle:
        rows = list(csv.DictReader(handle))
    assert len(rows) == EXPECTED_CANDIDATES, len(rows)

    with (OUTPUTS / "animal-target-summary.csv").open(
        newline="", encoding="utf-8"
    ) as handle:
        animal_summaries = list(csv.DictReader(handle))
    assert len(animal_summaries) == 18
    float32_animals = [
        row for row in animal_summaries if row["storage_format"] == "float32"
    ]
    assert len(float32_animals) == 6
    assert all(float(row["max_calibration_target_share"]) == 1.0 for row in float32_animals)
    assert all(int(row["perfect_calibration_candidates"]) > 0 for row in float32_animals)

    winner = results["winners_full_test"]["float32"]
    old_bits = int(winner["old_bits_hex"], 16)
    new_bits = int(winner["new_bits_hex"], 16)
    bit_index = int(winner["bit_index_from_lsb"])
    assert old_bits ^ new_bits == 1 << bit_index
    assert winner["effective_weight_elements_changed"] == 1
    assert results["controls"]["selected_float32_exactly_one_bit"] is True

    favorite = winner["target_class"]
    target_share = float(winner["full_test_target_share"])
    baseline_accuracy = float(results["baseline_float32_full_test"]["accuracy"])
    mutated_accuracy = float(winner["full_test_accuracy"])
    assert results["premise_passed"] is True
    assert manifest["premise_passed"] is True
    assert manifest["favorite_animal"] == favorite
    assert target_share >= 0.90
    assert baseline_accuracy - mutated_accuracy > 0.50

    with (OUTPUTS / "prediction-distributions.csv").open(
        newline="", encoding="utf-8"
    ) as handle:
        distributions = list(csv.DictReader(handle))
    scenarios = sorted({row["scenario"] for row in distributions})
    for scenario in scenarios:
        rows_for_scenario = [row for row in distributions if row["scenario"] == scenario]
        assert len(rows_for_scenario) == 10
        assert sum(int(row["prediction_count"]) for row in rows_for_scenario) == 10_000

    with (OUTPUTS / "winner-predictions.csv").open(newline="", encoding="utf-8") as handle:
        predictions = list(csv.DictReader(handle))
    assert len(predictions) == 10_000
    assert sum(row["mutated_prediction"] == favorite for row in predictions) == 9_994
    assert sum(float(row["winner_feature_activation"]) > 0 for row in predictions) == 9_994
    assert all(
        (row["mutated_prediction"] == favorite)
        == (float(row["winner_feature_activation"]) > 0)
        for row in predictions
    )

    print(
        json.dumps(
            {
                "verified": True,
                "files": len(manifest["files"]),
                "candidate_rows": len(rows),
                "animal_summary_rows": len(animal_summaries),
                "prediction_rows": len(predictions),
                "favorite_animal": favorite,
                "full_test_target_share": target_share,
                "baseline_accuracy": baseline_accuracy,
                "mutated_accuracy": mutated_accuracy,
            },
            indent=2,
        )
    )
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
