#!/usr/bin/env python3
import sys, struct, zlib

MAX_CHUNK_SIZE = 100

def main():
    uncomp = (b'GQOLELNFJH@?AQE@LBA=?@N@<GJHE=EGE<FQOAM@?<IABT>EK'
              b'<=QFRPBSRGFRENSJLDFGD=LSRHIAO?FB@NP?DGDS>NGT@CCFPS'
              b'A@B=IGG<?JQBGBPLOPONU?IBBSNBK<QAFLGK@>H=CQ?BS><@UE'
              b'QGAKHML@>?JOSEQRCTP>S<?N>DNM@??ARJ>QUJSHLQN<P<>D==')

    print("python", sys.version)
    print("zlib version", zlib.ZLIB_VERSION)
    print("zlib runtime version", zlib.ZLIB_RUNTIME_VERSION)

    chunks = compress(uncomp)
    decomp = decompress(chunks)
    assert(uncomp == decomp)


def compress(data):
    start_off = 0
    data_size = len(data)
    remaining = data_size
    res = []
    zdict = b''

    while start_off < data_size:
        print("compress chunk %d"%len(res))

        chunk_size = min(MAX_CHUNK_SIZE, remaining)
        chunk = data[start_off:start_off+chunk_size]
        c = b''

        z = zlib.compressobj(wbits=-15, zdict=zdict)
        c += z.compress(chunk)
        c += z.flush(zlib.Z_FINISH)

        res.append(c)

        zdict = chunk
        start_off += chunk_size
        remaining -= chunk_size

    return res

def decompress(chunks):
    zdict = b''
    res = []

    for i, c in enumerate(chunks):
        print("decompress chunk %d"%i)
        out = b''

        z = zlib.decompressobj(wbits=-15, zdict=zdict)
        out += z.decompress(c)
        out += z.flush()
        zdict = out

        res.append(out)

    return b''.join(res)


if __name__ == '__main__':
    main()
