#!/usr/bin/env python3
"""Create the H-01 canonical V3-contract source archive from a clean commit.

This local utility reads Git content only. It has no signing, wallet, RPC,
deployment, or broadcast capability. It refuses a source commit unless the
current canonical contract paths exactly match that reachable commit.
"""
from __future__ import annotations

import argparse
import hashlib
import tarfile
from io import BytesIO
from pathlib import Path

from validate_v3_candidate_manifest import check_clean_source_paths, committed_source_entries, source_tree_hash


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--repo-root", type=Path, required=True)
    parser.add_argument("--source-commit", required=True)
    parser.add_argument("--out", type=Path, required=True)
    args = parser.parse_args()

    entries, errors = committed_source_entries(args.repo_root, args.source_commit)
    errors.extend(check_clean_source_paths(args.repo_root, args.source_commit))
    if errors or entries is None:
        print("\n".join(errors or ["cannot construct canonical source archive"]))
        return 2

    with tarfile.open(args.out, "w", format=tarfile.USTAR_FORMAT) as archive:
        for name in sorted(entries):
            data = entries[name]
            member = tarfile.TarInfo(name)
            member.size = len(data)
            member.mode = 0o644
            member.uid = 0
            member.gid = 0
            member.uname = ""
            member.gname = ""
            member.mtime = 0
            archive.addfile(member, BytesIO(data))

    print("sourceTreeSha256=" + source_tree_hash(entries))
    print("sourceArchiveSha256=" + hashlib.sha256(args.out.read_bytes()).hexdigest())
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
