"""Portable source authentication and replay of C480; no external dependencies."""
import argparse
import hashlib
import json
from pathlib import Path
import runpy

ROOT = Path(__file__).resolve().parent.parent


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


def load(name):
    return json.loads((ROOT / "sources" / name).read_text())


def read(name):
    return (ROOT / "sources" / name).read_text()


def run(out):
    manifest = json.loads((ROOT / "SOURCE_MANIFEST.json").read_text())
    authentication = []
    for name, meta in manifest.items():
        p = ROOT / "sources" / name
        assert p.stat().st_size == meta["bytes"] and digest(p) == meta["sha256"], name
        authentication.append(name)
    anchors = {
        "File_18.md": "68301ab760bfbe2e874aedc5c8d943ced7a6219d34bc2859332a70713f9630d5",
        "File_09.md": "45851004c5864229ebf6a896f9099819a08d8926715d3e97e4bc3985c4a3876e",
        "C265_CERTIFICATE.json": "112bdcdd23e7580512f6b6a1c4222f746e6552f71b92755932397dbd25dce2de",
        "C127_GRAPH.json": "d7be8886117c8c550e39f8846862ec613f621c0ed560d4c9d8c89446fae53503",
        "PREVIOUS_CERTIFICATE.json": "ed81ad0635fbdf2d21e17da032c15b384bdb9ded8b500333c548a637f7ce1612",
    }
    for name, h in anchors.items():
        assert manifest[name]["sha256"] == h, name
        authentication.append("controlling hash: " + name)
    previous = load("PREVIOUS_CERTIFICATE.json")
    for key, name in [("data", "PREVIOUS_DATA.json"), ("results", "PREVIOUS_RESULTS.json"),
                      ("checkpoint", "PREVIOUS_CHECKPOINT.md"), ("report", "PREVIOUS_REPORT.md"),
                      ("next_step_decision", "PREVIOUS_NEXT_STEP.json")]:
        assert previous[key + "_sha256"] == manifest[name]["sha256"], name
        authentication.append("C479 binding: " + name)
    for step in [286, 450, 470, 471, 472]:
        c = load(f"C{step}_CERTIFICATE.json")
        for key in ["data", "results", "report"]:
            name = f"C{step}_{key.upper()}." + ("md" if key == "report" else "json")
            if name in manifest:
                assert c[key + "_sha256"] == manifest[name]["sha256"], name
                authentication.append(f"C{step} binding: {name}")
    checks = []

    def check(name, passed):
        assert passed, name
        assert name not in checks, name
        checks.append(name)

    data = runpy.run_path(str(ROOT / "evidence/CALCULATION.py"))["run"](load, read, check)
    results = {"step": "C480", "status": "passed", "assertions_passed": len(checks),
               "checks": checks, "source_checks_passed": len(authentication), "source_checks": authentication,
               "canonical_or_graph_edits": False, "new_independent_agent_review": False}
    out.mkdir(parents=True, exist_ok=True)
    for name, value in [("DATA.json", data), ("RESULTS.json", results)]:
        (out / name).write_text(json.dumps(value, ensure_ascii=False, indent=2) + "\n")
    print(json.dumps({"step": "C480", "status": "passed", "calculation_checks": len(checks),
                      "source_checks": len(authentication), "counts": data["counts"]}))


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--out", type=Path, required=True)
    args = parser.parse_args()
    run(args.out)
