"""Verify/extract an approved local release into a NEW directory. No services or downloads."""
import argparse
import hashlib
import io
import json
from pathlib import Path,PurePosixPath
import tarfile

MAX_BYTES=16*1024*1024
MAX_EXPANDED=64*1024*1024


def install(artifact,expected_sha256,destination):
    raw=Path(artifact).read_bytes()
    if len(raw)>MAX_BYTES or hashlib.sha256(raw).hexdigest()!=expected_sha256:
        raise ValueError('release checksum mismatch or size limit')
    import gzip
    with gzip.GzipFile(fileobj=io.BytesIO(raw)) as gz:expanded=gz.read(MAX_EXPANDED+1)
    if len(expanded)>MAX_EXPANDED:raise ValueError('expanded release size limit')
    files={}
    with tarfile.open(fileobj=io.BytesIO(expanded),mode='r:') as archive:
        for index,member in enumerate(archive):
            path=PurePosixPath(member.name)
            if index>=2000 or not member.name or member.name != path.as_posix() or '\\' in member.name or ':' in member.name or path.is_absolute() or '..' in path.parts or not member.isfile() or member.name in files:
                raise ValueError('unsafe release member')
            files[member.name]=archive.extractfile(member).read()
    names = set(files)
    for name in names:
        if any(parent.as_posix() in names for parent in PurePosixPath(name).parents if parent.as_posix() != '.'):
            raise ValueError('release file/directory collision')
    manifest=json.loads(files.pop('MANIFEST.json'))
    if {name:hashlib.sha256(data).hexdigest() for name,data in files.items()}!=manifest:
        raise ValueError('release member checksum mismatch')
    root=Path(destination)
    root.mkdir(mode=0o700,parents=False,exist_ok=False)
    for name,data in files.items():
        path=root/name;path.parent.mkdir(mode=0o755,parents=True,exist_ok=True)
        with open(path,'xb') as output:output.write(data)
    with open(root/'MANIFEST.json','x') as output:json.dump(manifest,output,sort_keys=True)
    return {'installed':str(root),'files':len(files),'activated':False,'keys_created':False,'dependency_installation':False}

if __name__=='__main__':
    parser=argparse.ArgumentParser();parser.add_argument('--artifact',required=True);parser.add_argument('--sha256',required=True);parser.add_argument('--destination',required=True)
    args=parser.parse_args();print(json.dumps(install(args.artifact,args.sha256,args.destination)))
