#!/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)])

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]}


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 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 and for Additional descriptors.

        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

        # Only initial descriptor type supported now
        descriptor_count = 1
        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

        initial_descriptor = device["InitialDescriptor"]
        initial_descriptor_type = initial_descriptor["InitialDescriptorType"]
        initial_descriptor_data = initial_descriptor["InitialDescriptorData"]

        # InitialDescriptorType
        if descriptor_type_name_length.get(initial_descriptor_type) is None:
            sys.exit("ERROR: Initial descriptor type not supported")
        record_length += 2

        # InitialDescriptorLength
        initial_descriptor_length = \
            len(bytearray.fromhex(initial_descriptor_data))
        if initial_descriptor_length != \
                descriptor_type_name_length.get(initial_descriptor_type)[1]:
            err_string = "ERROR: Initial descriptor type - " + \
                descriptor_type_name_length.get(initial_descriptor_type)[0] + \
                " length is incorrect"
            sys.exit(err_string)
        record_length += 2

        # InitialDescriptorData, the byte order in the JSON is retained.
        record_length += initial_descriptor_length

        format_string = '<HBIBBH' + \
            str(applicable_components_bitfield_length) + 's' + \
            str(len(component_image_set_version_string)) + 'sHH'
        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'),
                initial_descriptor_type,
                initial_descriptor_length))
        pldm_fw_up_pkg.write(bytearray.fromhex(initial_descriptor_data))


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]
        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
    '''
    file_size = pldm_fw_up_pkg.tell()
    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)
            write_pkg_header_checksum(pldm_fw_up_pkg)
            update_pkg_header_size(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()
