"""Check selected public archive bytes; require separate signer/provenance evidence."""
import argparse
import hashlib
import json
import os
import re
import subprocess
from pathlib import Path

REPOSITORY = "backbay-labs/chio"
TARGETS = ("x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu",
           "x86_64-apple-darwin", "aarch64-apple-darwin", "x86_64-pc-windows-msvc")


def review_archive(tag, target, expected_source, output):
    if not re.fullmatch(r"v[0-9]+\.[0-9]+\.[0-9]+(?:[-+][0-9A-Za-z.-]+)?", tag):
        raise ValueError("select an explicit version tag")
    if not re.fullmatch(r"[0-9a-f]{40}", expected_source):
        raise ValueError("select the independently reviewed public commit")
    output.mkdir(mode=0o700)

    def gh(*arguments):
        return subprocess.check_output(["gh", *arguments], text=True, timeout=120)

    reference = json.loads(gh("api", f"repos/{REPOSITORY}/git/ref/tags/{tag}"))["object"]
    while reference["type"] == "tag":
        reference = json.loads(gh("api", f"repos/{REPOSITORY}/git/tags/{reference['sha']}"))["object"]
    if reference["type"] != "commit" or reference["sha"] != expected_source:
        raise ValueError("public tag differs from the independently selected source commit")
    release = json.loads(gh("release", "view", tag, "--repo", REPOSITORY,
                            "--json", "tagName,isDraft,isPrerelease,assets"))
    assert release["tagName"] == tag and not release["isDraft"]
    with (output / "asset-inventory.json").open("x") as stream:
        json.dump(release, stream, indent=2)
        stream.write("\n")
    suffix = "zip" if target.endswith("msvc") else "tar.gz"
    archive = f"chio-{tag[1:]}-{target}.{suffix}"
    available = {asset["name"] for asset in release["assets"]}
    for name in (archive, archive + ".sha256", "SHA256SUMS"):
        if name not in available:
            raise ValueError(f"required checksum input is absent: {name}")
        gh("release", "download", tag, "--repo", REPOSITORY,
           "--pattern", name, "--dir", str(output))
    original = (output / archive).read_bytes()
    digest = hashlib.sha256(original).hexdigest()

    def selected_digest(text):
        matches = []
        for line in text.splitlines():
            columns = line.split()
            if len(columns) == 2 and columns[1].lstrip("*") == archive:
                if re.fullmatch(r"[0-9a-f]{64}", columns[0]):
                    matches.append(columns[0])
        if len(matches) != 1:
            raise ValueError("checksum file must contain exactly one selected archive entry")
        return matches[0]

    sidecar = selected_digest((output / (archive + ".sha256")).read_text())
    index = selected_digest((output / "SHA256SUMS").read_text())
    assert digest == sidecar == index, "archive differs from selected checksum records"
    print(f"CHECKSUM {archive}: selected sidecar and index match original bytes")
    changed = original[:-1] + bytes([original[-1] ^ 1])
    with (output / (archive + ".tampered")).open("xb") as stream:
        stream.write(changed)
    assert hashlib.sha256(changed).hexdigest() != sidecar
    print("REFUSE changed archive: selected checksum no longer matches")
    assert (output / archive).read_bytes() == original
    signed_inputs = {archive + ".sig", archive + ".pem",
                     f"chio-{expected_source}.intoto.jsonl"}
    missing = sorted(signed_inputs - available)
    if missing:
        print("INCOMPLETE signed-release acceptance: missing " + ", ".join(missing))
        print("SCOPE checksum comparison only; workflow identity and provenance remain unverified")
        return 4
    print("AVAILABLE signing inputs; independently pinned signature and five-subject provenance verification still required")
    return 0


if __name__ == "__main__":
    os.umask(0o077)
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--tag", required=True)
    parser.add_argument("--target", choices=TARGETS, required=True)
    parser.add_argument("--source-sha", required=True)
    parser.add_argument("--output", type=Path, required=True)
    args = parser.parse_args()
    raise SystemExit(review_archive(args.tag, args.target, args.source_sha, args.output))
