from __future__ import annotations

import hashlib
import json
from pathlib import Path


ROOT = Path(__file__).resolve().parent
PROJECT_RELATIVE_ROOT = "research/m3m-optical-disease-screening"
PDF = ROOT / "paper.pdf"
ARCHIVE = ROOT / "SHWRP-2026-033-v1.0.zip"
OUTPUT = ROOT / "zenodo-request.json"


def digest_file(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 descriptor(path: Path, media_type: str) -> dict[str, object]:
    return {
        "name": path.name,
        "path": f"{PROJECT_RELATIVE_ROOT}/{path.name}",
        "mediaType": media_type,
        "bytes": path.stat().st_size,
        "sha256": digest_file(path),
    }


def main() -> None:
    for path in (PDF, ARCHIVE):
        if not path.is_file():
            raise FileNotFoundError(path)
    payload = json.loads(OUTPUT.read_text(encoding="utf-8"))
    if payload.get("reportNumber") != "SHWRP-2026-033" or payload.get("version") != "1.0":
        raise RuntimeError("Refusing to modify a Zenodo request for another record or version")
    preserved = {key: payload.get(key) for key in ("title", "description", "rightsNote")}
    payload["files"] = [
        descriptor(PDF, "application/pdf"),
        descriptor(ARCHIVE, "application/zip"),
    ]
    if [item["name"] for item in payload["files"]] != ["paper.pdf", "SHWRP-2026-033-v1.0.zip"]:
        raise RuntimeError("Zenodo upload allowlist must contain exactly paper.pdf and the version ZIP")
    OUTPUT.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
    reloaded = json.loads(OUTPUT.read_text(encoding="utf-8"))
    if any(reloaded.get(key) != value for key, value in preserved.items()):
        raise RuntimeError("Zenodo title, description, or rightsNote changed unexpectedly")
    print(json.dumps({"status": "PASSED", "preserved": list(preserved), "files": payload["files"]}, ensure_ascii=False))


if __name__ == "__main__":
    main()
