#!/usr/bin/python3

import sys, os
from json import loads
import gzip
import struct
from base64 import b64encode

from viavi.qrcodegen import verizon as vz
from viavi.qrcodegen import QrCdmFactory, CdmProxy
from viavi.qrcodegen import QrCodeGenerator

from pprint import pformat


JSON_GZIP = 0


def make_header(fmt, *args) -> bytes:
    raw_header = [bytes([arg]) for arg in args]
    return b64encode(struct.pack(fmt, *raw_header))


def encode(data: str) -> bytes:
    raw = gzip.compress(data.encode('utf8'))
    return b64encode(raw)


def merge_cdms(files):
    data = dict()
    for filename in files:
        with open(filename, 'rb') as file:
            tmp = loads(file.read().decode('utf8'))
            if data == {}:
                data.update(tmp)

            else:
                data.get("tests", []).extend(tmp.get("tests", []))

    return CdmProxy(data)


# qrcodegen <-f|--format> [<format>] <--output-prefix> [<output_prefix>] <input_files>
if __name__ == "__main__":
    if len(sys.argv) < 3 or sys.argv[1] in ("-h", "--help"):
        print("Usage:\n\t%s <-f|--format> [<format>] <--output-prefix> [<output_prefix>] <input_files>" % sys.argv[0])
        exit(2)

    start_index = 1

    fmt = 0
    if sys.argv[1].strip() in ("-f", "--format"):
        fmt = sys.argv[2].strip()

        fmt = int(fmt) if fmt != "vz" else fmt

        start_index += 2

    output = "./output"
    if len(sys.argv) > 3:
        if sys.argv[3].strip() in ("--output-prefix",):
            output = sys.argv[4].strip()

            start_index += 2

    cdm = merge_cdms(sys.argv[start_index:])

    if fmt == "vz":
        data_factory = vz.QrCdmFactory(cdm)

        print("-> step 1: create json data")
        data = data_factory.create_json_lite()
        print(pformat(data.data))

        print("-> step 2: compress")
        compressed_data = data.compress()
        print(compressed_data)

        print("-> step 3: encode")
        encoded_data = vz.CommonSpec.encode(compressed_data)
        print(encoded_data)

        gen = QrCodeGenerator()

        gen.generate(data=encoded_data,
                     content_type=data.format,
                     make_header=vz.CommonSpec.make_header)

        gen.save(output)

    elif fmt == 0:
        data_factory = QrCdmFactory(cdm)

        print("-> step 1: create json data")
        data = data_factory.create_json_lite()
        print(pformat(data))

        print("-> step 2: compress")
        compressed_data = data
        print(compressed_data)

        print("-> step 3: encode")
        encoded_data = encode(compressed_data)
        print(encoded_data)

        gen = QrCodeGenerator()

        gen.generate(data=encoded_data,
                     content_type=JSON_GZIP,
                     make_header=make_header)