## @file
# Module that encodes and decodes a FMP_PAYLOAD_HEADER with a payload.
# The FMP_PAYLOAD_HEADER is processed by the FmpPayloadHeaderLib in the
# FmpDevicePkg.
#
# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution.  The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#

'''
FmpPayloadHeader
'''

import struct

def _SIGNATURE_32 (A, B, C, D):
    return struct.unpack ('=I',bytearray (A + B + C + D, 'ascii'))[0]

def _SIGNATURE_32_TO_STRING (Signature):
    return struct.pack ("<I", Signature).decode ()

class FmpPayloadHeaderClass (object):
    #
    # typedef struct {
    #   UINT32  Signature;
    #   UINT32  HeaderSize;
    #   UINT32  FwVersion;
    #   UINT32  LowestSupportedVersion;
    # } FMP_PAYLOAD_HEADER;
    #
    # #define FMP_PAYLOAD_HEADER_SIGNATURE SIGNATURE_32 ('M', 'S', 'S', '1')
    #
    _StructFormat = '<IIII'
    _StructSize   = struct.calcsize (_StructFormat)

    _FMP_PAYLOAD_HEADER_SIGNATURE = _SIGNATURE_32 ('M', 'S', 'S', '1')

    def __init__ (self):
        self._Valid                 = False
        self.Signature              = self._FMP_PAYLOAD_HEADER_SIGNATURE
        self.HeaderSize             = self._StructSize
        self.FwVersion              = 0x00000000
        self.LowestSupportedVersion = 0x00000000
        self.Payload                = b''

    def Encode (self):
        FmpPayloadHeader = struct.pack (
                                     self._StructFormat,
                                     self.Signature,
                                     self.HeaderSize,
                                     self.FwVersion,
                                     self.LowestSupportedVersion
                                     )
        self._Valid = True
        return FmpPayloadHeader + self.Payload

    def Decode (self, Buffer):
        if len (Buffer) < self._StructSize:
            raise ValueError
        (Signature, HeaderSize, FwVersion, LowestSupportedVersion) = \
            struct.unpack (
                     self._StructFormat,
                     Buffer[0:self._StructSize]
                     )
        if Signature != self._FMP_PAYLOAD_HEADER_SIGNATURE:
            raise ValueError
        if HeaderSize < self._StructSize:
            raise ValueError
        self.Signature              = Signature
        self.HeaderSize             = HeaderSize
        self.FwVersion              = FwVersion
        self.LowestSupportedVersion = LowestSupportedVersion
        self.Payload                = Buffer[self.HeaderSize:]

        self._Valid                 = True
        return self.Payload

    def DumpInfo (self):
        if not self._Valid:
            raise ValueError
        print ('FMP_PAYLOAD_HEADER.Signature              = {Signature:08X} ({SignatureString})'.format (Signature = self.Signature, SignatureString = _SIGNATURE_32_TO_STRING (self.Signature)))
        print ('FMP_PAYLOAD_HEADER.HeaderSize             = {HeaderSize:08X}'.format (HeaderSize = self.HeaderSize))
        print ('FMP_PAYLOAD_HEADER.FwVersion              = {FwVersion:08X}'.format (FwVersion = self.FwVersion))
        print ('FMP_PAYLOAD_HEADER.LowestSupportedVersion = {LowestSupportedVersion:08X}'.format (LowestSupportedVersion = self.LowestSupportedVersion))
        print ('sizeof (Payload)                          = {Size:08X}'.format (Size = len (self.Payload)))
