"""Decode only two exact native ZIP members; no path from ZIP controls output."""
from pathlib import Path
import hashlib
import json
import struct
import zlib


def prepare_profiles(directory):
    outputs = []
    for member in json.loads(Path('native-members.json').read_text()):
        compressed = (directory/member['range_file']).read_bytes()
        if hashlib.sha256(compressed).hexdigest() != member['range_sha256']:
            raise ValueError('Native HTTP span hash changed')
        if compressed[:4] != b'PK\x03\x04' or struct.unpack_from('<H', compressed, 8)[0] != 8:
            raise ValueError('Named span is not a deflated local ZIP member')
        name_length, extra_length = struct.unpack_from('<HH', compressed, 26)
        if compressed[30:30+name_length].decode() != member['name']:
            raise ValueError('Wrong native member name')
        start = 30+name_length+extra_length
        inflater = zlib.decompressobj(-15)
        original = inflater.decompress(compressed[start:start+member['compressed']], member['uncompressed']+1)
        if len(original) != member['uncompressed'] or not inflater.eof or inflater.unconsumed_tail:
            raise ValueError('Expanded native member exceeds exact declared size')
        if hashlib.sha256(original).hexdigest() != member['sha256'] or zlib.crc32(original) != member['crc32']:
            raise ValueError('Native member original-byte hash/CRC changed')
        (directory/member['profile_file']).write_bytes(original)
        outputs.append({'name': member['name'], 'output': member['profile_file'], 'bytes': len(original),
                        'sha256': member['sha256'], 'license': member['license'], 'attribution': member['attribution']})
    return outputs
