#!/usr/bin/env python3
import sys
import mxf_analyzer

##--------------------
##    CRAPPY  CODE
##     prototype
##--------------------

# -----------------------------------------------------------------------------------
# Les différents programmes ci-dessous sont des POC (proof-of-concept),
# leurs codes ne sont pas optimisés et méritent une réécriture totale (c'est prévu…)
# cependant, ils sont fonctionnels pour les besoins de cette documentation.
# -----------------------------------------------------------------------------------


smpte = mxf_analyzer.SMPTE()

# merge all UL
uls = {}
for k, v in {**smpte.picture_essence_coding}.items():
    uls[k] = {'name': v}
smpte.universal_labels = {**smpte.universal_labels, **uls} 


if len(sys.argv) <= 1:
    print("Usage: %s <--dump> <-v> <ul>")
    sys.exit(1)


# -----------------------------------------------------------------
if "--dump" in sys.argv:
    for key, description in {**smpte.universal_labels}.items():
        print("%-32s \t %s" % (
            key,
            description.get('name', ''),
        ))
        if "-v" in sys.argv:
            for index, resource in enumerate(description.get('resource', '(No resource)').split(','), 1):
                print("%32s \t ↪ %s" % ('', resource.strip()))
    sys.exit(0)
# -----------------------------------------------------------------



ul = sys.argv[1]
ul = ul.replace('.', '').replace(' ', '').replace("0x", '').replace(',', '')

if ul[0:8].lower() != '060e2b34':
    print("%s is a wrong UL" % ul)
    sys.exit(1)


class KLV(object):
    uuid = None
klv = KLV()
klv.uuid = bytes.fromhex(ul)


formatting = {}

if len(klv.uuid) == 16:
    formatting["SMPTE UL Format"] = "{:02x}{:02x}{:02x}{:02x}.{:02x}{:02x}{:02x}{:02x}.{:02x}{:02x}{:02x}{:02x}.{:02x}{:02x}{:02x}{:02x}".format(*klv.uuid)
    formatting["Hex Format (lower)"] = "{:02x}.{:02x}.{:02x}.{:02x}.{:02x}.{:02x}.{:02x}.{:02x}.{:02x}.{:02x}.{:02x}.{:02x}.{:02x}.{:02x}.{:02x}.{:02x}".format(*klv.uuid)
    formatting["Hex Format (upper)"] = "{:02X}.{:02X}.{:02X}.{:02X}.{:02X}.{:02X}.{:02X}.{:02X}.{:02X}.{:02X}.{:02X}.{:02X}.{:02X}.{:02X}.{:02X}.{:02X}".format(*klv.uuid)
    formatting["Hex Format (small)"] = "{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}".format(*klv.uuid)
    formatting["─"*46] = '─'*100

for k, v in smpte.match_uuid(klv.uuid.hex()).items():
    formatting[k] = v;
formatting["─"*45] = '─'*100

formatting['UL Header (2 bytes)'] = klv.uuid[0:2].hex()
# UL designator is not the 8 latest bytes ?
formatting['UL Designator (6 bytes)'] = klv.uuid[2:8].hex()
formatting['Item Designator (8 bytes)'] = klv.uuid[8:].hex()
formatting["─"*44] = '─'*100

formatting["1 - Object ID"] = klv.uuid[0:1].hex()
formatting["2 - UL Size"] = "%s (%s bytes)" % (klv.uuid[1:2].hex(), int.from_bytes(klv.uuid[1:2], byteorder='big'))
if klv.uuid[1:2] != b'\x0e':
    formatting["2 - UL Size"] += " (Wrong UL Size, not SMPTE compliant)"

formatting["3 - ISO/ORG Identifier / UL Code"] = klv.uuid[2:3].hex()
formatting["4 - SMPTE Designator"] = klv.uuid[3:4].hex()

# Category Type
formatting["5 - Category Designator"] = klv.uuid[4:5].hex()  # SMPTE-336M - Table 3 – UL Designator
if klv.uuid[4:5].hex() == '01'       : formatting["5 - Category Designator"] += " (Dictionaries)"
if klv.uuid[4:5].hex() == '02'       : formatting["5 - Category Designator"] += " (Groups - Sets & Packs)"
if klv.uuid[4:5].hex() == '03'       : formatting["5 - Category Designator"] += " (Wrappers & Containers)"
if klv.uuid[4:5].hex() == '04'       : formatting["5 - Category Designator"] += " (Labels Register)"
if klv.uuid[4:5].hex() == '05'       : formatting["5 - Category Designator"] += " (Registered Private Information)"
if b'\x06' < klv.uuid[4:5] < b'\x7E' : formatting["5 - Category Designator"] += " (Reserved)"

# Registry Type 
formatting["6 - Registry Designator"] = klv.uuid[5:6].hex()

if klv.uuid[4:6].hex() == '0101': formatting["6 - Registry Designator"] += " (Metadata Dictonary)"
if klv.uuid[4:6].hex() == '0102': formatting["6 - Registry Designator"] += " (Essence Dictonary)"
if klv.uuid[4:6].hex() == '0103': formatting["6 - Registry Designator"] += " (Control Dictonary)"
if klv.uuid[4:6].hex() == '0104': formatting["6 - Registry Designator"] += " (Types Dictonary)"

if klv.uuid[4:6].hex() == '0201': formatting["6 - Registry Designator"] += " (Universal Set)"

# Global Set
global_set = {
    "0202": "(Global Set) - [Length=BER short/long] (All Length)",
    "0222": "(Global Set) - [Length=1 byte] (Length to 255)",
    "0242": "(Global Set) - [Length=2 bytes] (Length to 65535)",
    "0262": "(Global Set) - [Length=4 bytes] (Length to 2^32-1)",
}
try:
    formatting["6 - Registry Designator"] += " " + global_set[klv.uuid[4:6].hex()]
except:
    pass

# Local Sets
local_sets = {
    "0203": "(Local Sets) - [LocalTag=1 byte - Length=BER short/long] (All Length)",
    "020B": "(Local Sets) - [LocalTag=BER OID - Length=BER short/long] (All Length)",
    "0213": "(Local Sets) - [LocalTag=2 bytes - Length=BER short/long] (All Length)",
    "021B": "(Local Sets) - [LocalTag=4 bytes - Length=BER short/long] (All Length)",
    "0223": "(Local Sets) - [LocalTag=1 byte - Length=1 byte] (Length to 255)",
    "022B": "(Local Sets) - [LocalTag=BER OID - Length=1 byte] (Length to 255)",
    "0233": "(Local Sets) - [LocalTag=2 bytes - Length=1 byte] (Length to 255)",
    "023B": "(Local Sets) - [LocalTag=4 bytes - Length=1 byte] (Length to 255)",
    "0243": "(Local Sets) - [LocalTag=1 byte - Length=2 bytes] (Length to 65535)",
    "024B": "(Local Sets) - [LocalTag=BER OID - Length=2 bytes] (Length to 65535)",
    "0253": "(Local Sets) - [LocalTag=2 bytes - Length=2 bytes] (Length to 65535)",
    "025B": "(Local Sets) - [LocalTag=4 bytes - Length=2 bytes] (Length to 65535)",
    "0263": "(Local Sets) - [LocalTag=1 byte - Length=4 bytes] (Length to 2^32-1)",
    "026B": "(Local Sets) - [LocalTag=BER OID - Length=4 bytes] (Length to 2^32-1)",
    "0273": "(Local Sets) - [LocalTag=2 bytes - Length=4 bytes] (Length to 2^32-1)",
    "027B": "(Local Sets) - [LocalTag=4 bytes - Length=4 bytes] (Length to 2^32-1)",
}
try:
    formatting["6 - Registry Designator"] += " " + local_sets[klv.uuid[4:6].hex()]
except:
    pass

# Variable-Length Pack
variable_length_pack = {
    "0204": "(Variable-Length Pack) - [Length=BER short/long] (All Length)",
    "0224": "(Variable-Length Pack) - [Length=1 byte] (Length to 255)",
    "0244": "(Variable-Length Pack) - [Length=2 bytes] (Length to 65535)",
    "0264": "(Variable-Length Pack) - [Length=4 bytes] (Length to 2^32-1)",
}
try:
    formatting["6 - Registry Designator"] += " " + variable_length_pack[klv.uuid[4:6].hex()]
except:
    pass

# Fixed-Length Pack
if klv.uuid[4:6].hex() == '0205': formatting["6 - Registry Designator"] += " (Fixed Length Pack)"
if klv.uuid[4:6].hex() == '0206': formatting["6 - Registry Designator"] += " (Reserved / Forbidden)"

# Wrappers
if klv.uuid[4:6].hex() == '0301': formatting["6 - Registry Designator"] += " (Simple Wrappers & Containers)"
if klv.uuid[4:6].hex() == '0302': formatting["6 - Registry Designator"] += " (Complex Wrappers & Containers)"


#-------------------------------------------------------------------
formatting["7 - Structure Designator"] = klv.uuid[6:7].hex() # SMPTE-336M - Table 3 – UL Designator

if klv.uuid[4:5].hex() + klv.uuid[6:7].hex() == '0201': formatting["7 - Structure Designator"] += " (Set/Pack Registry)"
if klv.uuid[4:5].hex() + klv.uuid[6:7].hex() == '0401': formatting["7 - Structure Designator"] += " (Labels)"

formatting["8 - Version"] = klv.uuid[7:8].hex()

# Item Designator
formatting["─"*47] = '─'*100
for i in range(8, 16):
    formatting["%d - Item Designator" % (i+1)] = klv.uuid[i:i+1].hex()


#--------------------------------------------------------------------

for key, value in formatting.items():
    if value is not None:
        print("\t ║\t{key:40s}\t{value}".format(key=key, value=value))

