#!/usr/bin/env python3

"""Script to create PLDM FW update package"""

import argparse
import binascii
from datetime import datetime
import json
import os
import struct
import sys

import math
from bitarray import bitarray
from bitarray.util import ba2int

string_types = dict([
    ("Unknown", 0),
    ("ASCII", 1),
    ("UTF8", 2),
    ("UTF16", 3),
    ("UTF16LE", 4),
    ("UTF16BE", 5)])

initial_descriptor_type_name_length = {
    0x0000: ["PCI Vendor ID", 2],
    0x0001: ["IANA Enterprise ID", 4],
    0x0002: ["UUID", 16],
    0x0003: ["PnP Vendor ID", 3],
    0x0004: ["ACPI Vendor ID", 4]}

descriptor_type_name_length = {
    0x0000: ["PCI Vendor ID", 2],
    0x0001: ["IANA Enterprise ID", 4],
    0x0002: ["UUID", 16],
    0x0003: ["PnP Vendor ID", 3],
    0x0004: ["ACPI Vendor ID", 4],
    0x0100: ["PCI Device ID", 2],
    0x0101: ["PCI Subsystem Vendor ID", 2],
    0x0102: ["PCI Subsystem ID", 2],
    0x0103: ["PCI Revision ID", 1],
    0x0104: ["PnP Product Identifier", 4],
    0x0105: ["ACPI Product Identifier", 4]}


def check_string_length(string):
    """Check if the length of the string is not greater than 255."""
    if len(string) > 255:
        sys.exit("ERROR: Max permitted string length is 255")


def write_pkg_release_date_time(pldm_fw_up_pkg, release_date_time):
    '''
    Write the timestamp into the package header. The timestamp is formatted as
    series of 13 bytes defined in DSP0240 specification.

        Parameters:
            pldm_fw_up_pkg: PLDM FW update package
            release_date_time: Package Release Date Time
    '''
    time = release_date_time.time()
    date = release_date_time.date()
    us_bytes = time.microsecond.to_bytes(3, byteorder='little')
    pldm_fw_up_pkg.write(
        struct.pack(
            '<hBBBBBBBBHB',
            0,
            us_bytes[0],
            us_bytes[1],
            us_bytes[2],
            time.second,
            time.minute,
            time.hour,
            date.day,
            date.month,
            date.year,
            0))


def write_package_version_string(pldm_fw_up_pkg, metadata):
    '''
    Write PackageVersionStringType, PackageVersionStringLength and
    PackageVersionString to the package header.

        Parameters:
            pldm_fw_up_pkg: PLDM FW update package
            metadata: metadata about PLDM FW update package
    '''
    # Hardcoded string type to ASCII
    string_type = string_types["ASCII"]
    package_version_string = \
        metadata["PackageHeaderInformation"]["PackageVersionString"]
    check_string_length(package_version_string)
    format_string = '<BB' + str(len(package_version_string)) + 's'
    pldm_fw_up_pkg.write(
        struct.pack(
            format_string,
            string_type,
            len(package_version_string),
            package_version_string.encode('ascii')))


def write_component_bitmap_bit_length(pldm_fw_up_pkg, metadata):
    '''
    ComponentBitmapBitLength in the package header indicates the number of bits
    that will be used represent the bitmap in the ApplicableComponents field
    for a matching device. The value shall be a multiple of 8 and be large
    enough to contain a bit for each component in the package. The number of
    components in the JSON file is used to populate the bitmap length.

        Parameters:
            pldm_fw_up_pkg: PLDM FW update package
            metadata: metadata about PLDM FW update package

        Returns:
            ComponentBitmapBitLength: number of bits that will be used
            represent the bitmap in the ApplicableComponents field for a
            matching device
    '''
    # The script supports upto 32 components now
    max_components = 32
    bitmap_multiple = 8

    num_components = len(metadata["ComponentImageInformationArea"])
    if num_components > max_components:
        sys.exit("ERROR: only upto 32 components supported now")
    component_bitmap_bit_length = bitmap_multiple * \
        math.ceil(num_components/bitmap_multiple)
    pldm_fw_up_pkg.write(struct.pack('<H', int(component_bitmap_bit_length)))
    return component_bitmap_bit_length


def write_pkg_header_info(pldm_fw_up_pkg, metadata):
    '''
    ComponentBitmapBitLength in the package header indicates the number of bits
    that will be used represent the bitmap in the ApplicableComponents field
    for a matching device. The value shall be a multiple of 8 and be large
    enough to contain a bit for each component in the package. The number of
    components in the JSON file is used to populate the bitmap length.

        Parameters:
            pldm_fw_up_pkg: PLDM FW update package
            metadata: metadata about PLDM FW update package

        Returns:
            ComponentBitmapBitLength: number of bits that will be used
            represent the bitmap in the ApplicableComponents field for a
            matching device
    '''
    uuid = metadata["PackageHeaderInformation"]["PackageHeaderIdentifier"]
    package_header_identifier = bytearray.fromhex(uuid)
    pldm_fw_up_pkg.write(package_header_identifier)

    package_header_format_revision = \
        metadata["PackageHeaderInformation"]["PackageHeaderFormatVersion"]
    # Size will be computed and updated subsequently
    package_header_size = 0
    pldm_fw_up_pkg.write(
        struct.pack(
            '<BH',
            package_header_format_revision,
            package_header_size))

    try:
        release_date_time = datetime.strptime(
            metadata["PackageHeaderInformation"]["PackageReleaseDateTime"],
            "%d/%m/%Y %H:%M:%S")
        write_pkg_release_date_time(pldm_fw_up_pkg, release_date_time)
    except KeyError:
        write_pkg_release_date_time(pldm_fw_up_pkg, datetime.now())

    component_bitmap_bit_length = write_component_bitmap_bit_length(
        pldm_fw_up_pkg, metadata)
    write_package_version_string(pldm_fw_up_pkg, metadata)
    return component_bitmap_bit_length


def get_applicable_components(device, components, component_bitmap_bit_length):
    '''
    This function figures out the components applicable for the device and sets
    the ApplicableComponents bitfield accordingly.

        Parameters:
            device: device information
            components: list of components in the package
            component_bitmap_bit_length: length of the ComponentBitmapBitLength

        Returns:
            The ApplicableComponents bitfield
    '''
    applicable_components_list = device["ApplicableComponents"]
    applicable_components = bitarray(component_bitmap_bit_length,
                                     endian='little')
    applicable_components.setall(0)
    for component in components:
        if component["ComponentIdentifier"] in applicable_components_list:
            applicable_components[components.index(component)] = 1
    return applicable_components


def prepare_record_descriptors(descriptors):
    '''
    This function processes the Descriptors and prepares the RecordDescriptors
    section of the the firmware device ID record.

        Parameters:
            descriptors: Descriptors entry

        Returns:
            RecordDescriptors, DescriptorCount
    '''
    record_descriptors = bytearray()
    vendor_defined_desc_type = 65535
    vendor_desc_title_str_type_len = 1
    vendor_desc_title_str_len_len = 1
    descriptor_count = 0

    for descriptor in descriptors:

        descriptor_type = descriptor["DescriptorType"]
        if descriptor_count == 0:
            if initial_descriptor_type_name_length.get(descriptor_type) \
                    is None:
                sys.exit("ERROR: Initial descriptor type not supported")
        else:
            if descriptor_type_name_length.get(descriptor_type) is None and \
                    descriptor_type != vendor_defined_desc_type:
                sys.exit("ERROR: Descriptor type not supported")

        if descriptor_type == vendor_defined_desc_type:
            vendor_desc_title_str = \
                descriptor["VendorDefinedDescriptorTitleString"]
            vendor_desc_data = descriptor["VendorDefinedDescriptorData"]
            check_string_length(vendor_desc_title_str)
            vendor_desc_title_str_type = string_types["ASCII"]
            descriptor_length = vendor_desc_title_str_type_len + \
                vendor_desc_title_str_len_len + len(vendor_desc_title_str) + \
                len(bytearray.fromhex(vendor_desc_data))
            format_string = '<HHBB' + str(len(vendor_desc_title_str)) + 's'
            record_descriptors.extend(struct.pack(
                format_string,
                descriptor_type,
                descriptor_length,
                vendor_desc_title_str_type,
                len(vendor_desc_title_str),
                vendor_desc_title_str.encode('ascii')))
            record_descriptors.extend(bytearray.fromhex(vendor_desc_data))
            descriptor_count += 1
        else:
            descriptor_type = descriptor["DescriptorType"]
            descriptor_data = descriptor["DescriptorData"]
            descriptor_length = len(bytearray.fromhex(descriptor_data))
            if descriptor_length != \
                    descriptor_type_name_length.get(descriptor_type)[1]:
                err_string = "ERROR: Descriptor type - " + \
                    descriptor_type_name_length.get(descriptor_type)[0] + \
                    " length is incorrect"
                sys.exit(err_string)
            format_string = '<HH'
            record_descriptors.extend(struct.pack(
                format_string,
                descriptor_type,
                descriptor_length))
            record_descriptors.extend(bytearray.fromhex(descriptor_data))
            descriptor_count += 1
    return record_descriptors, descriptor_count


def write_fw_device_identification_area(pldm_fw_up_pkg, metadata,
                                        component_bitmap_bit_length):
    '''
    Write firmware device ID records into the PLDM package header

    This function writes the DeviceIDRecordCount and the
    FirmwareDeviceIDRecords into the firmware update package by processing the
    metadata JSON. Currently there is no support for optional
    FirmwareDevicePackageData.

        Parameters:
            pldm_fw_up_pkg: PLDM FW update package
            metadata: metadata about PLDM FW update package
            component_bitmap_bit_length: length of the ComponentBitmapBitLength
    '''
    # The spec limits the number of firmware device ID records to 255
    max_device_id_record_count = 255
    devices = metadata["FirmwareDeviceIdentificationArea"]
    device_id_record_count = len(devices)
    if device_id_record_count > max_device_id_record_count:
        sys.exit(
            "ERROR: there can be only upto 255 entries in the \
                FirmwareDeviceIdentificationArea section")

    # DeviceIDRecordCount
    pldm_fw_up_pkg.write(struct.pack('<B', device_id_record_count))

    for device in devices:
        # RecordLength size
        record_length = 2

        # DescriptorCount
        record_length += 1

        # DeviceUpdateOptionFlags
        device_update_option_flags = bitarray(32, endian='little')
        device_update_option_flags.setall(0)
        # Continue component updates after failure
        supported_device_update_option_flags = [0]
        for option in device["DeviceUpdateOptionFlags"]:
            if option not in supported_device_update_option_flags:
                sys.exit("ERROR: unsupported DeviceUpdateOptionFlag entry")
            device_update_option_flags[option] = 1
        record_length += 4

        # ComponentImageSetVersionStringType supports only ASCII for now
        component_image_set_version_string_type = string_types["ASCII"]
        record_length += 1

        # ComponentImageSetVersionStringLength
        component_image_set_version_string = \
            device["ComponentImageSetVersionString"]
        check_string_length(component_image_set_version_string)
        record_length += len(component_image_set_version_string)
        record_length += 1

        # Optional FirmwareDevicePackageData not supported now,
        # FirmwareDevicePackageDataLength is set to 0x0000
        fw_device_pkg_data_length = 0
        record_length += 2

        # ApplicableComponents
        components = metadata["ComponentImageInformationArea"]
        applicable_components = \
            get_applicable_components(device,
                                      components,
                                      component_bitmap_bit_length)
        applicable_components_bitfield_length = \
            round(len(applicable_components)/8)
        record_length += applicable_components_bitfield_length

        # RecordDescriptors
        descriptors = device["Descriptors"]
        record_descriptors, descriptor_count = \
            prepare_record_descriptors(descriptors)
        record_length += len(record_descriptors)

        format_string = '<HBIBBH' + \
            str(applicable_components_bitfield_length) + 's' + \
            str(len(component_image_set_version_string)) + 's'
        pldm_fw_up_pkg.write(
            struct.pack(
                format_string,
                record_length,
                descriptor_count,
                ba2int(device_update_option_flags),
                component_image_set_version_string_type,
                len(component_image_set_version_string),
                fw_device_pkg_data_length,
                applicable_components.tobytes(),
                component_image_set_version_string.encode('ascii')))
        pldm_fw_up_pkg.write(record_descriptors)


def write_component_image_info_area(pldm_fw_up_pkg, metadata, image_files):
    '''
    Write component image information area into the PLDM package header

    This function writes the ComponentImageCount and the
    ComponentImageInformation into the firmware update package by processing
    the metadata JSON. Currently there is no support for
    ComponentComparisonStamp field and the component option use component
    comparison stamp.

    Parameters:
        pldm_fw_up_pkg: PLDM FW update package
        metadata: metadata about PLDM FW update package
        image_files: component images
    '''
    components = metadata["ComponentImageInformationArea"]
    # ComponentImageCount
    pldm_fw_up_pkg.write(struct.pack('<H', len(components)))
    component_location_offsets = []
    # ComponentLocationOffset position in individual component image
    # information
    component_location_offset_pos = 12

    for component in components:
        # Record the location of the ComponentLocationOffset to be updated
        # after appending images to the firmware update package
        component_location_offsets.append(pldm_fw_up_pkg.tell() +
                                          component_location_offset_pos)

        # ComponentClassification
        component_classification = component["ComponentClassification"]
        if component_classification < 0 or component_classification > 0xFFFF:
            sys.exit(
                "ERROR: ComponentClassification should be [0x0000 - 0xFFFF]")

        # ComponentIdentifier
        component_identifier = component["ComponentIdentifier"]
        if component_identifier < 0 or component_identifier > 0xFFFF:
            sys.exit(
                "ERROR: ComponentIdentifier should be [0x0000 - 0xFFFF]")

        # ComponentComparisonStamp not supported
        component_comparison_stamp = 0xFFFFFFFF

        # ComponentOptions
        component_options = bitarray(16, endian='little')
        component_options.setall(0)
        supported_component_options = [0, 1, 2]
        for option in component["ComponentOptions"]:
            if option not in supported_component_options:
                sys.exit(
                    "ERROR: unsupported ComponentOption in\
                    ComponentImageInformationArea section")
            component_options[option] = 1

        # RequestedComponentActivationMethod
        requested_component_activation_method = bitarray(16, endian='little')
        requested_component_activation_method.setall(0)
        supported_requested_component_activation_method = [0, 1, 2, 3, 4, 5]
        for option in component["RequestedComponentActivationMethod"]:
            if option not in supported_requested_component_activation_method:
                sys.exit(
                    "ERROR: unsupported RequestedComponent\
                        ActivationMethod entry")
            requested_component_activation_method[option] = 1

        # ComponentLocationOffset
        component_location_offset = 0
        # ComponentSize
        component_size = 0
        # ComponentVersionStringType
        component_version_string_type = string_types["ASCII"]
        # ComponentVersionStringlength
        # ComponentVersionString
        component_version_string = component["ComponentVersionString"]
        check_string_length(component_version_string)

        format_string = '<HHIHHIIBB' + str(len(component_version_string)) + 's'
        pldm_fw_up_pkg.write(
            struct.pack(
                format_string,
                component_classification,
                component_identifier,
                component_comparison_stamp,
                ba2int(component_options),
                ba2int(requested_component_activation_method),
                component_location_offset,
                component_size,
                component_version_string_type,
                len(component_version_string),
                component_version_string.encode('ascii')))

    index = 0
    pkg_header_checksum_size = 4
    start_offset = pldm_fw_up_pkg.tell() + pkg_header_checksum_size
    # Update ComponentLocationOffset and ComponentSize for all the components
    for offset in component_location_offsets:
        file_size = os.stat(image_files[index]).st_size
        pldm_fw_up_pkg.seek(offset)
        pldm_fw_up_pkg.write(
            struct.pack(
                '<II', start_offset, file_size))
        start_offset += file_size
        index += 1
    pldm_fw_up_pkg.seek(0, os.SEEK_END)


def write_pkg_header_checksum(pldm_fw_up_pkg):
    '''
    Write PackageHeaderChecksum into the PLDM package header.

        Parameters:
            pldm_fw_up_pkg: PLDM FW update package
    '''
    pldm_fw_up_pkg.seek(0)
    package_header_checksum = binascii.crc32(pldm_fw_up_pkg.read())
    pldm_fw_up_pkg.seek(0, os.SEEK_END)
    pldm_fw_up_pkg.write(struct.pack('<I', package_header_checksum))


def update_pkg_header_size(pldm_fw_up_pkg):
    '''
    Update PackageHeader in the PLDM package header. The package header size
    which is the count of all bytes in the PLDM package header structure is
    calculated once the package header contents is complete.

        Parameters:
            pldm_fw_up_pkg: PLDM FW update package
    '''
    pkg_header_checksum_size = 4
    file_size = pldm_fw_up_pkg.tell() + pkg_header_checksum_size
    pkg_header_size_offset = 17
    # Seek past PackageHeaderIdentifier and PackageHeaderFormatRevision
    pldm_fw_up_pkg.seek(pkg_header_size_offset)
    pldm_fw_up_pkg.write(struct.pack('<H', file_size))
    pldm_fw_up_pkg.seek(0, os.SEEK_END)


def append_component_images(pldm_fw_up_pkg, image_files):
    '''
    Append the component images to the firmware update package.

        Parameters:
            pldm_fw_up_pkg: PLDM FW update package
            image_files: component images
    '''
    for image in image_files:
        with open(image, 'rb') as file:
            for line in file:
                pldm_fw_up_pkg.write(line)


def main():
    """Create PLDM FW update (DSP0267) package based on a JSON metadata file"""
    parser = argparse.ArgumentParser()
    parser.add_argument("pldmfwuppkgname",
                        help="Name of the PLDM FW update package")
    parser.add_argument("metadatafile", help="Path of metadata JSON file")
    parser.add_argument(
        "images", nargs='+',
        help="One or more firmware image paths, in the same order as\
            ComponentImageInformationArea entries")

    args = parser.parse_args()
    image_files = args.images
    with open(args.metadatafile) as file:
        try:
            metadata = json.load(file)
        except ValueError:
            sys.exit("ERROR: Invalid metadata JSON file")

    # Validate the number of component images
    if len(image_files) != len(metadata["ComponentImageInformationArea"]):
        sys.exit("ERROR: number of images passed != number of entries \
            in ComponentImageInformationArea")

    try:
        with open(args.pldmfwuppkgname, 'w+b') as pldm_fw_up_pkg:
            component_bitmap_bit_length = write_pkg_header_info(pldm_fw_up_pkg,
                                                                metadata)
            write_fw_device_identification_area(pldm_fw_up_pkg,
                                                metadata,
                                                component_bitmap_bit_length)
            write_component_image_info_area(pldm_fw_up_pkg, metadata,
                                            image_files)
            update_pkg_header_size(pldm_fw_up_pkg)
            write_pkg_header_checksum(pldm_fw_up_pkg)
            append_component_images(pldm_fw_up_pkg, image_files)
            pldm_fw_up_pkg.close()
    except BaseException:
        pldm_fw_up_pkg.close()
        os.remove(args.pldmfwuppkgname)
        raise


if __name__ == "__main__":
    main()
