#!/usr/bin/env python3
"""Download pinned official releases; verify upstream SHA256 before extraction."""
import concurrent.futures
import hashlib
import json
from pathlib import Path
import subprocess
import tarfile

ROOT = Path(__file__).resolve().parents[1]
releases = json.loads((ROOT / 'metadata/releases.json').read_text())

def download(f):
    dest = ROOT / 'downloads' / f['name']
    subprocess.run(['curl', '-fL', '--retry', '3', '--connect-timeout', '30',
                    '--max-time', '1800', '-o', str(dest) + '.part', f['url']], check=True)
    Path(str(dest) + '.part').replace(dest)
    if (f.get('digest') or '').startswith('sha256:'):
        assert hashlib.sha256(dest.read_bytes()).hexdigest() == f['digest'][7:], dest

with concurrent.futures.ThreadPoolExecutor(max_workers=3) as pool:
    list(pool.map(download, [f for r in releases for f in r['files']]))
for r in releases:
    checksums = next(f for f in r['files'] if f['name'].endswith('checksums.txt'))
    entries = {}
    for line in (ROOT / 'downloads' / checksums['name']).read_text().splitlines():
        parts = line.split()
        if len(parts) == 2:
            entries[parts[1].lstrip('*')] = parts[0]
    archive = ROOT / 'downloads' / r['asset']
    actual = hashlib.sha256(archive.read_bytes()).hexdigest()
    if actual != entries.get(r['asset']):
        raise RuntimeError('Upstream checksum mismatch: ' + r['asset'])
    target = ROOT / 'bin' / r['tool']
    if archive.name.endswith('.tar.gz'):
        with tarfile.open(archive) as tf:
            member = tf.getmember(r['tool'])
            if not member.isfile():
                raise RuntimeError('Not a regular binary')
            target.write_bytes(tf.extractfile(member).read())
            for member in tf.getmembers():
                if member.isfile() and Path(member.name).name.lower().startswith('license'):
                    (ROOT / 'metadata' / (r['tool'] + '-LICENSE')).write_bytes(tf.extractfile(member).read())
    else:
        target.write_bytes(archive.read_bytes())
    target.chmod(0o755)
    print(r['tool'], r['version'], actual, 'upstream checksum verified', flush=True)
