from __future__ import annotations

import hashlib
import json

import pytest

from obliteratus.checkpoint_evaluation import (
    _partition_pairs,
    _verify_checkpoint_inventory,
)


def test_protocol_evaluation_partitions_are_immutable_and_disjoint():
    tune = _partition_pairs("optimizer_tune")
    final = _partition_pairs("final_test")

    assert len(tune) == 142
    assert len(final) == 200
    assert set(tune).isdisjoint(final)
    with pytest.raises(ValueError, match="unsupported"):
        _partition_pairs("training")


def test_checkpoint_inventory_verifies_size_hash_and_managed_path(tmp_path):
    run_dir = tmp_path / ("run-" + "a" * 32)
    checkpoint = run_dir / "checkpoint"
    checkpoint.mkdir(parents=True)
    weights = checkpoint / "weights.bin"
    weights.write_bytes(b"verified weights")
    inventory = run_dir / "artifact-inventory.json"
    inventory.write_text(
        json.dumps(
            {
                "artifacts": [
                    {
                        "path": "checkpoint/weights.bin",
                        "bytes": weights.stat().st_size,
                        "sha256": hashlib.sha256(weights.read_bytes()).hexdigest(),
                    }
                ]
            }
        ),
        encoding="utf-8",
    )
    manifest = {
        "result": {"checkpoint": str(checkpoint), "inventory": str(inventory)}
    }

    assert _verify_checkpoint_inventory(run_dir, manifest) == checkpoint.resolve()
    weights.write_bytes(b"tampered weights")
    with pytest.raises(ValueError, match="hash changed"):
        _verify_checkpoint_inventory(run_dir, manifest)
