#!/usr/bin/env python3
'''
unpack a param.pck file from @PARAM/param.pck via mavlink FTP
'''

import struct, sys

from argparse import ArgumentParser
parser = ArgumentParser(description=__doc__)
parser.add_argument("file", metavar="LOG")

args = parser.parse_args()

data = open(args.file,'rb').read()
last_name = ""

magic = 0x671b

# header of 6 bytes
magic2,num_params,total_params = struct.unpack("<HHH", data[0:6])
if magic != magic2:
    print("Bad magic 0x%x expected 0x%x" % (magic2, magic))
    sys.exit(1)

data = data[6:]

# mapping of data type to type length and format
data_types = {
    1: (1, 'b'),
    2: (2, 'h'),
    3: (4, 'i'),
    4: (4, 'f'),
}


# we discard leading pad bytes (zero) on all params
# pad bytes are inserted to ensure that a value doesn't
# cross a block boundary
pad_byte = 0
if sys.version_info.major < 3:
    pad_byte = chr(0)

count = 0

while True:
    # skip pad bytes
    while len(data) > 0 and data[0] == pad_byte:
        data = data[1:]

    if len(data) == 0:
        break

    ptype, plen = struct.unpack("<BB", data[0:2])
    flags = (ptype>>4) & 0x0F
    ptype &= 0x0F

    if ptype not in data_types:
        raise Exception("bad type 0x%x" % ptype)

    (type_len, type_format) = data_types[ptype]

    name_len = ((plen>>4) & 0x0F) + 1
    common_len = (plen & 0x0F)
    name = last_name[0:common_len] + data[2:2+name_len].decode('utf-8')
    vdata = data[2+name_len:2+name_len+type_len]
    last_name = name
    data = data[2+name_len+type_len:]
    v, = struct.unpack("<" + type_format, vdata)
    count += 1
    print("%-16s %f" % (name, float(v)))

if count != num_params or count > total_params:
    print("Error: Got %u params expected %u/%u" % (count, num_params, total_params))
    sys.exit(1)
sys.exit(0)