"""Tests that manifest.json sha256 values match actual file hashes."""

import hashlib
import json
from milco.cli import main


def _sha256_of(path):
    return hashlib.sha256(path.read_bytes()).hexdigest()


def _write_contract(tmp_path):
    contract = tmp_path / "TASK_CONTRACT.md"
    contract.write_text(
        "# Task Contract\n\n"
        "## Goal\n\nTest.\n\n"
        "## Scope\n\nTest.\n\n"
        "## Out of scope\n\nNone.\n\n"
        "## Success Criteria\n\nPass.\n\n"
        "## Constraints\n\nNone.\n\n"
        "## Approvals required\n\nNone.\n\n"
        "## Notes\n\nNone.\n",
        encoding="utf-8",
    )
    return contract


def test_summary_hash_matches(tmp_path, monkeypatch):
    contract = _write_contract(tmp_path)
    monkeypatch.chdir(tmp_path)

    main(["run", "--contract", str(contract), "--run-id", "h-sum"])

    run_dir = tmp_path / "runs" / "h-sum"
    data = json.loads((run_dir / "manifest.json").read_text(encoding="utf-8"))
    actual_hash = _sha256_of(run_dir / "summary.md")
    assert data["artifacts"]["summary.md"]["sha256"] == actual_hash


def test_patches_hash_matches(tmp_path, monkeypatch):
    contract = _write_contract(tmp_path)
    monkeypatch.chdir(tmp_path)

    main(["run", "--contract", str(contract), "--run-id", "h-patch"])

    run_dir = tmp_path / "runs" / "h-patch"
    data = json.loads((run_dir / "manifest.json").read_text(encoding="utf-8"))
    actual_hash = _sha256_of(run_dir / "patches.diff")
    assert data["artifacts"]["patches.diff"]["sha256"] == actual_hash


def test_evidence_hash_matches(tmp_path, monkeypatch):
    contract = _write_contract(tmp_path)
    monkeypatch.chdir(tmp_path)

    main(["run", "--contract", str(contract), "--run-id", "h-evi"])

    run_dir = tmp_path / "runs" / "h-evi"
    data = json.loads((run_dir / "manifest.json").read_text(encoding="utf-8"))
    actual_hash = _sha256_of(run_dir / "evidence.md")
    assert data["artifacts"]["evidence.md"]["sha256"] == actual_hash


def test_byte_counts_match(tmp_path, monkeypatch):
    contract = _write_contract(tmp_path)
    monkeypatch.chdir(tmp_path)

    main(["run", "--contract", str(contract), "--run-id", "h-bytes"])

    run_dir = tmp_path / "runs" / "h-bytes"
    data = json.loads((run_dir / "manifest.json").read_text(encoding="utf-8"))
    for name in ["summary.md", "patches.diff", "evidence.md", "gate_report.json"]:
        expected_bytes = (run_dir / name).stat().st_size
        assert data["artifacts"][name]["bytes"] == expected_bytes, (
            f"Byte mismatch for {name}"
        )
