class RootKey(Structure):
    _fields = [
        ("type", UInt32LE),
        ("spare1", Padding(fixed_size=4)),
        ("key", DataOffset),
        ("spare2", Padding(pad_to=0x0020)),
    ]
class AuthSig(Structure):
    _fields = [
        ("data", DataOffset),
        ("sig", DataOffset),
        ("type", UInt32LE),
        ("spare", Padding(pad_to=0x0020)),
    ]
class OptionData(Structure):
    _fields = [
        ("flags", UInt32LE),
        ("fpga_opt1", UInt32LE),
        ("hps_opt1", UInt32LE),
        ("hps_opt2", UInt32LE),
        ("spare", Padding(pad_to=0x0040)),
    ]
class SecHeader(Structure):
    _fields = [
        ("magic", UInt32LE),
        ("version", UInt32LE),
        ("header_length", UInt32LE),
        ("load_length", UInt32LE),
        ("number_of_sigs", UInt32LE),
        ("offset_to_checksum", UInt32LE),
        ("flags", UInt32LE),
        ("size_after_decryption", UInt32LE),
        ("date", UInt64LE),
        ("dummy_clocks_to_write", UInt32LE),
        ("spare", Padding(pad_to=0x0100)),
    ]
class AuthHeader(Structure):
    # sec_header:
    #  0x0000 magic
    #  0x0004 version
    #  0x0008 header_length
    #  0x000C load_length
    #  0x0010 number_of_sigs
    #  0x0014 offset_to_checksum
    #  0x0018 flags
    #  0x001C size_after_decryption
    #  0x0020 date
    #  0x0028 dummy_clocks_to_write
    #  0x002C..0x0100 reserved
    # option_data:
    #  0x0100 flags
    #  0x0104 fpga_opt1
    #  0x0108 hps_opt1
    #  0x010C hps_opt2
    #  0x0110..0x0140 reserved
    # reserved:
    #  0x0140..0x0200 reserved
    # root_key:
    #  0x0200 type
    #  0x0204 reserved
    #  0x0208 key (DataOffset)
    #  0x0210..0x0220 reserved
    # auth_image:
    #  0x0220 type
    #  0x0224 data (DataOffset)
    #  0x022C sig (DataOffset)
    #  0x0234..0x0240 reserved
    # reserved:
    #  0x0240..0x0400 reserved
    # [if using any subroot keys:]
    # auth_sig_0:
    #  0x0400 data (DataOffset)
    #  0x0408 sig (DataOffset)
    #  0x0410 type
    #  0x0414..0x0420 reserved
    # auth_sig_<n>:
    #  0x0420 data
    #  0x0428 sig
    #  0x0430 type
    #  0x0434..0x0440 reserved
    # ...

    _fields = [
        ("sec_header", SecHeader),
        ("option_data", OptionData),
        ("spare1", Padding(pad_to=0x0200)),
        ("root_key", RootKey),
        ("auth_image", AuthImage),
        ("spare2", Padding(pad_to=0x0400)),
        ("auth_sig", StructureList([], AuthSig)),
    ]

    _update_hooks = {
        'auth_sig': lambda s: s.update_num_sigs(),
        'sec_header.number_of_sigs': lambda s: s.update_auth_sig_length(),
    }

    def update_auth_sig_length(self):
        self.auth_sig.truncate(self.sec_header.number_of_sigs)

    def update_num_sigs(self):
        self.sec_header.number_of_sigs = len(self.auth_sig)