#!/usr/bin/env python3
"""Create the publishable evidence bundle with deterministic paths and hashes."""
from __future__ import annotations

import hashlib
import json
import zipfile
from pathlib import Path

OUT = Path(__file__).resolve().parents[1]
ZIP = OUT / "evidence-bundle.zip"
MANIFEST = OUT / "evidence-file-manifest.sha256"

FILES = [
    "executive-summary.md", "full-report.md", "preregistration.md",
    "preregistration-university-news-addendum.md", "methodology.md", "codebook.md",
    "limitations.md", "claim-ledger.csv", "articles.csv", "article-coding.csv",
    "actor-level-analysis.csv", "leadership-timeline.csv", "leadership.json", "results.json",
    "chart-data.json", "sources.csv", "corpus-readme.md", "corpus-manifest.json",
    "data-dictionary.md", "results.schema.json", "requirements.txt", "run-analysis.sh",
    "manual-audit.csv", "university-manual-audit.csv", "university-manual-coder-a.csv",
    "university-manual-coder-b.csv", "university-manual-adjudicated-overlap.csv",
    "university-manual-parser-repair-review.csv", "university-manual-sample-manifest.json",
    "university-manual-intercoder-reliability.csv", "university-automation-validation.csv",
    "university-validation-results.json", "university-manual-results.json",
    "leadership-exploratory-results.json", "automated-screening-results.json",
    "automated-screening-results-prefixed-topic.json",
    "automated-screening-results-prefixed-corpus-parser.json",
    "automated-method-change-log.md", "corpus-parser-repair-log.md",
    "university-methods-factcheck.md",
    "scripts/university_automated_analysis.py",
    "scripts/university_automated_analysis_frozen.py",
    "scripts/build_public_automated_outputs.py",
    "scripts/build_authorized_articles.py",
    "scripts/select_university_manual_sample.py",
    "scripts/prepare_university_adjudication.py",
    "scripts/finalize_university_manual.py",
    "scripts/build_university_manual_adjudicated.py",
    "scripts/build_university_manual_parser_repair_review.py",
    "scripts/analyze_university_manual.py",
    "scripts/analyze_university_validation.py",
    "scripts/analyze_leadership_exploratory.py",
    "scripts/build_university_results.py",
    "scripts/repair_http_records.py",
    "scripts/normalize_repaired_descriptions.py",
    "scripts/check_package.py",
    "scripts/build_evidence_bundle.py",
]


def digest(path: Path) -> str:
    return hashlib.sha256(path.read_bytes()).hexdigest()


def main():
    missing = [name for name in FILES if not (OUT / name).is_file()]
    assert not missing, f"missing bundle files: {missing}"
    forbidden = [name for name in FILES if Path(name).suffix.lower() in {".docx", ".html", ".htm"} or "private-university-corpus" in name]
    assert not forbidden, forbidden
    lines = [f"{digest(OUT / name)}  research-output/{name}" for name in sorted(FILES)]
    MANIFEST.write_text("\n".join(lines) + "\n", encoding="utf-8")
    bundle_files = FILES + [MANIFEST.name]
    with zipfile.ZipFile(ZIP, "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as archive:
        for name in sorted(bundle_files):
            archive.write(OUT / name, arcname=f"research-output/{name}")
    with zipfile.ZipFile(ZIP) as archive:
        names = archive.namelist()
        assert len(names) == len(bundle_files) and len(names) == len(set(names))
        assert all(name.startswith("research-output/") for name in names)
        assert not any(name.endswith((".docx", ".html", ".htm")) or "private-university-corpus" in name for name in names)
    print(json.dumps({
        "bundle": str(ZIP), "files": len(bundle_files), "bytes": ZIP.stat().st_size,
        "sha256": digest(ZIP), "copyrighted_bodies_included": False,
    }, indent=2))


if __name__ == "__main__":
    main()
