#!/usr/bin/env python2.7

'''
This program will take truseted application's manifest config JSON file as
input. Processes the JSON config file and creates packed data
mapping to C structures and dumps in binary format.

USAGE:
    manifest_compiler.py --input <input_filename> --output <output_filename> \
        --constants <config_constants_file_1> \
        --constants <config_constants_file_2> \
        --header-dir <header_file_path>

    Arguments:
    input_filename  - Trusted app manifest config file in JSON format.
    output_filename - Binary file containing packed manifest config data mapped
                      to C structres.
    config_constant_file - This is optional
                    Config file with constants in JSON format
                    Corresponding header file will be
                    created with its constants defined in it
    header_file_path - Directory in which header files to be generated.

    example:
        manifest_compiler.py --input manifest.json --output output.bin \
                --constants manifest_constants.json \
                --header-dir \
                <build_dir>/user_tasks/trusty/user/app/sample/hwcrypto/include


   Input sample JSON Manifest config file content -
   {
        "uuid": "SECURE_STORAGE_SERVER_APP_UUID",
        "min_heap": 4096,
        "min_stack": 4096,
        "mem_map": [{"id": 1, "addr": "0x70000000", "size": "0x1000"}, \
                {"id": 2, "addr": "0x70010000", "size": "0x100"}, \
                {"id": 3, "addr": "0x70020000", "size": "0x4",
                 "type": "uncached_device", "non_secure": false}],
        "mgmt_flags": {"restart_on_exit": true, \
                "deferred_start": false, \
                "non_critical_app": false},
        "start_ports": [{"name": "LOADABLE_START_PORT", \
                "flags": {"allow_ta_connect": true, "allow_ns_connect": false}}]
   }

   JSON manifest constant config -
   {
        "header": "storage_constants.h",
        "constants": [{
            "name": "LOADABLE_START_PORT",
            "value": "com.android.trusty.appmgmt.loadable.start",
            "type": "port"
        },
        {
            "name": "SECURE_STORAGE_SERVER_APP_UUID",
            "value": "eca48f94-00aa-560e-8f8c-d94b50d484f3",
            "type": "uuid"
        }]
    }
'''

import argparse
import cStringIO
import json
import optparse
import os.path
import struct
import sys


# Manifest properties
UUID = "uuid"
MIN_HEAP = "min_heap"
MIN_STACK = "min_stack"
MEM_MAP = "mem_map"
MEM_MAP_ID = "id"
MEM_MAP_ADDR = "addr"
MEM_MAP_SIZE = "size"
MEM_MAP_TYPE = "type"
MEM_MAP_TYPE_CACHED = "cached"
MEM_MAP_TYPE_UNCACHED = "uncached"
MEM_MAP_TYPE_UNCACHED_DEVICE = "uncached_device"
MEM_MAP_NON_SECURE = "non_secure"
MGMT_FLAGS = "mgmt_flags"
MGMT_FLAG_RESTART_ON_EXIT = "restart_on_exit"
MGMT_FLAG_DEFERRED_START = "deferred_start"
MGMT_FLAG_NON_CRITICAL_APP = "non_critical_app"
START_PORTS = "start_ports"
START_PORT_FLAGS = "flags"
START_PORT_NAME = "name"
START_PORT_ALLOW_TA_CONNECT = "allow_ta_connect"
START_PORT_ALLOW_NS_CONNECT = "allow_ns_connect"
APP_NAME = "app_name"

# constants configs
CONSTANTS = "constants"
HEADER = "header"
CONST_NAME = "name"
CONST_VALUE = "value"
CONST_TYPE = "type"
CONST_UNSIGNED = "unsigned"
CONST_PORT = "port"
CONST_UUID = "uuid"
CONST_INT = "int"
CONST_BOOL = "bool"

# CONFIG TAGS
# These values need to be kept in sync with uapi/trusty_app_manifest_types.h
TRUSTY_APP_CONFIG_KEY_MIN_STACK_SIZE = 1
TRUSTY_APP_CONFIG_KEY_MIN_HEAP_SIZE = 2
TRUSTY_APP_CONFIG_KEY_MAP_MEM = 3
TRUSTY_APP_CONFIG_KEY_MGMT_FLAGS = 4
TRUSTY_APP_CONFIG_KEY_START_PORT = 5

# MEM_MAP ARCH_MMU_FLAGS
# These values need to be kept in sync with external/lk/include/arch/mmu.h
ARCH_MMU_FLAG_CACHED = 0 << 0
ARCH_MMU_FLAG_UNCACHED = 1 << 0
ARCH_MMU_FLAG_UNCACHED_DEVICE = 2 << 0
ARCH_MMU_FLAG_CACHE_MASK = 3 << 0
ARCH_MMU_FLAG_NS = 1 << 5

# MGMT FLAGS
# These values need to be kept in sync with uapi/trusty_app_manifest_types.h
TRUSTY_APP_MGMT_FLAGS_NONE = 0
TRUSTY_APP_MGMT_FLAGS_RESTART_ON_EXIT = 1 << 0
TRUSTY_APP_MGMT_FLAGS_DEFERRED_START = 1 << 1
TRUSTY_APP_MGMT_FLAGS_NON_CRITICAL_APP = 1 << 2

# START_PORT flags
# These values need to be kept in sync with user/base/include/user/trusty_ipc.h
IPC_PORT_ALLOW_TA_CONNECT = 0x1
IPC_PORT_ALLOW_NS_CONNECT = 0x2

IPC_PORT_PATH_MAX = 64


class Constant(object):
    def __init__(self, name, value, type_, unsigned=False, hex_num=False):
        self.name = name
        self.value = value
        self.type = type_
        self.unsigned = unsigned
        self.hex_num = hex_num


class ConfigConstants(object):
    def __init__(self, constants, header):
        self.constants = constants
        self.header = header


class StartPortFlags(object):
    def __init__(self, allow_ta_connect, allow_ns_connect):
        self.allow_ta_connect = allow_ta_connect
        self.allow_ns_connect = allow_ns_connect


class StartPort(object):
    def __init__(self, name, name_size, start_port_flags):
        self.name = name
        self.name_size = name_size
        self.start_port_flags = start_port_flags


class MemIOMap(object):
    def __init__(self, id_, addr, size, type, non_secure):
        self.id = id_
        self.addr = addr
        self.size = size
        self.type = type
        self.non_secure = non_secure


class MgmtFlags(object):
    def __init__(self, restart_on_exit, deferred_start, non_critical_app):
        self.restart_on_exit = restart_on_exit
        self.deferred_start = deferred_start
        self.non_critical_app = non_critical_app


'''
Holds Manifest data to be used for packing
'''
class Manifest(object):
    def __init__(
            self,
            uuid,
            app_name,
            min_heap,
            min_stack,
            mem_io_maps,
            mgmt_flags,
            start_ports
    ):
        self.uuid = uuid
        self.app_name = app_name
        self.min_heap = min_heap
        self.min_stack = min_stack
        self.mem_io_maps = mem_io_maps
        self.mgmt_flags = mgmt_flags
        self.start_ports = start_ports


'''
Tracks errors during manifest compilation
'''
class Log(object):
    def __init__(self):
        self.error_count = 0

    def error(self, msg):
        sys.stderr.write("Error: {}\n".format(msg))
        self.error_count += 1

    def error_occurred(self):
        return self.error_count > 0


'''
For the given manifest JSON field it returns its literal value type mapped.
'''
def get_string_sub_type(field):
    if field == UUID:
        return CONST_UUID
    elif field == START_PORT_NAME:
        return CONST_PORT
    else:
        # field with string value but doesn't support a constant
        return None


def get_constant(constants, key, type_, log):
    const = constants.get(key)
    if const is None:
        return None

    if const.type != type_:
        log.error("{} constant type mismatch, expected type is {}"
                  .format(key, type_))
        return None

    return const.value


'''
Determines whether the value for the given key in dictionary is of type string
and if it is a string then returns the value.
'''
def get_string(manifest_dict, key, constants, log, optional=False,
               default=None):
    if key not in manifest_dict:
        if not optional:
            log.error("Manifest is missing required attribute - {}"
                      .format(key))
        return default

    value = manifest_dict.pop(key)

    # try to check is this field holding a constant
    type_ = get_string_sub_type(key)
    if type_:
        const_value = get_constant(constants, value, type_, log)
        if const_value is not None:
            return const_value

    return coerce_to_string(value, key, log)


def coerce_to_string(value, key, log):
    if not isinstance(value, str) and \
            not isinstance(value, unicode):
        log.error(
                "Invalid value for" +
                " {} - \"{}\", Valid string value is expected"
                .format(key, value))
        return None

    return value


'''
Determines whether the value for the given key in dictionary is of type integer
and if it is int then returns the value
'''
def get_int(manifest_dict, key, constants, log, optional=False,
            default=None):
    if key not in manifest_dict:
        if not optional:
            log.error("Manifest is missing required attribute - {}"
                      .format(key))
        return default

    value = manifest_dict.pop(key)
    const_value = get_constant(constants, value, CONST_INT, log)
    if const_value is not None:
        return const_value

    return coerce_to_int(value, key,log)


def coerce_to_int(value, key, log):
    if isinstance(value, int) and \
            not isinstance(value, bool):
        return value
    elif isinstance(value, basestring):
        try:
            return int(value, 0)
        except ValueError as ex:
            log.error("Invalid value for" +
                      " {} - \"{}\", valid integer or hex string is expected"
                      .format(key, value))
            return None
    else:
        log.error("Invalid value for" +
                  " {} - \"{}\", valid integer value is expected"
                  .format(key, value))
        return None


'''
Determines whether the value for the given key in dictionary is of type List
and if it is List then returns the value
'''
def get_list(manifest_dict, key, log, optional=False, default=None):
    if key not in manifest_dict:
        if not optional:
            log.error("Manifest is missing required attribute - {}"
                      .format(key))
        return default

    return coerce_to_list(manifest_dict.pop(key), key, log)


def coerce_to_list(value, key, log):
    if not isinstance(value, list):
        log.error("Invalid value for" +
                  " {} - \"{}\", valid list is expected"
                  .format(key, value))
        return None

    return value


'''
Determines whether the value for the given
key in dictionary is of type Dictionary
and if it is Dictionary then returns the value
'''
def get_dict(manifest_dict, key, log, optional=False, default=None):
    if key not in manifest_dict:
        if not optional:
            log.error("Manifest is missing required attribute - {}"
                      .format(key))
        return default

    return coerce_to_dict(manifest_dict.pop(key), key, log)


def coerce_to_dict(value, key, log):
    if not isinstance(value, dict):
        log.error("Invalid value for" +
                  " {} - \"{}\", valid dict is expected"
                  .format(key, value))
        return None

    return value


'''
Determines whether the value for the given key in dictionary is of type boolean
and if it is boolean then returns the value
'''
def get_boolean(manifest_dict, key, constants, log, optional=False,
                default=None):
    if key not in manifest_dict:
        if not optional:
            log.error("Manifest is missing required attribute - {}"
                      .format(key))
        return default

    value = manifest_dict.pop(key)
    const_value = get_constant(constants, value, CONST_BOOL, log)
    if const_value is not None:
        return const_value

    return coerce_to_boolean(value, key, log)


def coerce_to_boolean(value, key, log):
    if not isinstance(value, bool):
        log.error(
                "Invalid value for" +
                " {} - \"{}\", Valid boolean value is expected"
                .format(key, value))
        return None

    return value


def get_uuid(manifest_dict, key, constants, log, optional=False, default=None):
    if key not in manifest_dict:
        if not optional:
            log.error("Manifest is missing required attribute - {}"
                      .format(key))
        return default

    uuid = get_string(manifest_dict, key, {}, log, optional, default)
    const_value = get_constant(constants, uuid, CONST_UUID, log)
    if const_value is not None:
        return const_value

    return parse_uuid(uuid, log)


def get_port(port, key, constants, log, optional=False, default=None):
    return get_string(port, key, constants, log, optional, default)


'''
Validate and arrange UUID byte order
If its valid UUID then returns 16 byte UUID
'''
def parse_uuid(uuid, log):
    if uuid is None:
        return None

    # Example UUID: "5f902ace-5e5c-4cd8-ae54-87b88c22ddaf"
    if len(uuid) != 36:
        log.error(
                "Invalid UUID " +
                "{}, uuid should be of length 16 bytes of hex values"
                .format(uuid))
        return None

    uuid_data = uuid.split("-")
    if len(uuid_data) != 5:
        log.error(
                "Invalid UUID {}".format(uuid) +
                "uuid should be of length 16 bytes of hex divided into 5 groups"
                )
        return None

    try:
        uuid_data = [part.decode("hex") for part in uuid_data]
    except TypeError as ex:
        log.error("Invalid UUID {}, {}".format(uuid, ex))
        return None

    if len(uuid_data[0]) != 4 or \
            len(uuid_data[1]) != 2 or \
            len(uuid_data[2]) != 2 or \
            len(uuid_data[3]) != 2 or \
            len(uuid_data[4]) != 6:
        log.error("Wrong grouping of UUID - {}".format(uuid))
        return None

    return "".join(uuid_data)


'''
Validate memory size value.
if success return memory size value else return None
'''
def parse_memory_size(memory_size, log):
    if memory_size is None:
        return None

    if memory_size <= 0 or memory_size % 4096 != 0:
        log.error(
                "{}: {}, Minimum memory size should be "
                .format(MIN_STACK, memory_size) +
                "non-negative multiple of 4096")
        return None

    return memory_size


def parse_mem_map_type(mem_map_type, log):
    if mem_map_type not in {MEM_MAP_TYPE_CACHED,
                            MEM_MAP_TYPE_UNCACHED,
                            MEM_MAP_TYPE_UNCACHED_DEVICE}:
        log.error("Unknown mem_map.type entry in manifest: {} "
                  .format(mem_map_type))

    return mem_map_type


def parse_mem_map(mem_maps, key, constants, log):
    if mem_maps is None:
        return None

    mem_io_maps = []
    for mem_map_entry in mem_maps:
        mem_map_entry = coerce_to_dict(mem_map_entry, key, log)
        if mem_map_entry is None:
            continue
        mem_map = MemIOMap(
                get_int(mem_map_entry, MEM_MAP_ID, constants, log),
                get_int(mem_map_entry, MEM_MAP_ADDR, constants, log),
                get_int(mem_map_entry, MEM_MAP_SIZE, constants, log),
                parse_mem_map_type(
                        get_string(mem_map_entry, MEM_MAP_TYPE, constants, log,
                                   optional=True,
                                   default=MEM_MAP_TYPE_UNCACHED_DEVICE), log),
                get_boolean(mem_map_entry, MEM_MAP_NON_SECURE, constants, log,
                            optional=True)
                )
        if mem_map_entry:
            log.error("Unknown atributes in mem_map entries in manifest: {} "
                      .format(mem_map_entry))
        mem_io_maps.append(mem_map)

    return mem_io_maps


def parse_mgmt_flags(flags, constants, log):
    if flags is None:
        return None

    mgmt_flags = MgmtFlags(
            get_boolean(flags, MGMT_FLAG_RESTART_ON_EXIT, constants, log, optional=True),
            get_boolean(flags, MGMT_FLAG_DEFERRED_START, constants, log, optional=True),
            get_boolean(flags, MGMT_FLAG_NON_CRITICAL_APP, constants, log, optional=True))

    if flags:
        log.error("Unknown atributes in mgmt_flags entries in manifest: {} "
                  .format(flags))

    return mgmt_flags


def parse_app_start_ports(start_port_list, key, constants, log):
    start_ports = []

    for port_entry in start_port_list:
        port_entry = coerce_to_dict(port_entry, key, log)
        if port_entry is None:
            continue

        name = get_port(port_entry, START_PORT_NAME, constants, log)
        if len(name) >= IPC_PORT_PATH_MAX:
            log.error("Length of start port name should be less than {}"
                      .format(IPC_PORT_PATH_MAX))

        flags = get_dict(port_entry, START_PORT_FLAGS, log)
        start_ports_flag = None
        if flags:
            start_ports_flag = StartPortFlags(
                    get_boolean(flags, START_PORT_ALLOW_TA_CONNECT, constants,
                                log),
                    get_boolean(flags, START_PORT_ALLOW_NS_CONNECT, constants,
                                log))

        if port_entry:
            log.error("Unknown atributes in start_ports entries" +
                      " in manifest: {} ".format(port_entry))
        if flags:
            log.error("Unknown atributes in start_ports.flags entries" +
                      " in manifest: {} ".format(flags))

        start_ports.append(StartPort(name, len(name), start_ports_flag))

    return start_ports


def parse_app_name(app_name, log):
    if app_name is None:
        return None

    if not app_name:
        log.error("empty app-name is not allowed in manifest")
        return None

    return app_name.strip()


'''
validate the manifest config and extract key, values
'''
def parse_manifest_config(manifest_dict, constants, default_app_name, log):
    # UUID
    uuid = get_uuid(manifest_dict, UUID, constants, log)

    # MIN_HEAP
    min_heap = parse_memory_size(get_int(manifest_dict, MIN_HEAP, constants,
                                         log), log)

    # MIN_STACK
    min_stack = parse_memory_size(get_int(manifest_dict, MIN_STACK, constants,
                                          log), log)

    # MEM_MAP
    mem_io_maps = parse_mem_map(
            get_list(manifest_dict, MEM_MAP, log, optional=True, default=[]),
            MEM_MAP,
            constants, log)

    # MGMT_FLAGS
    mgmt_flags = parse_mgmt_flags(
            get_dict(manifest_dict, MGMT_FLAGS, log, optional=True,
                     default={
                             MGMT_FLAG_RESTART_ON_EXIT: False,
                             MGMT_FLAG_DEFERRED_START: False,
                             MGMT_FLAG_NON_CRITICAL_APP: False}),
                     constants, log)

    # START_PORTS
    start_ports = parse_app_start_ports(
            get_list(manifest_dict, START_PORTS, log,
                     optional=True, default=[]),
            START_PORTS,
            constants,
            log)

    #APP_NAME
    app_name = parse_app_name(
            get_string(manifest_dict, APP_NAME, constants, log,
                       optional=True, default=default_app_name), log)

    # look for any extra attributes
    if manifest_dict:
        log.error("Unknown atributes in manifest: {} ".format(manifest_dict))

    if log.error_occurred():
        return None

    return Manifest(uuid, app_name, min_heap, min_stack, mem_io_maps, mgmt_flags,
                    start_ports)


'''
This script represents UUIDs in a purely big endian order.
Trusty stores the first three components of the UUID in little endian order.
Rearrange the byte order accordingly by doing inverse
on first three components of UUID
'''
def swap_uuid_bytes(uuid):
    return uuid[3::-1] + uuid[5:3:-1] + uuid[7:5:-1] + uuid[8:]


def pack_mem_map_arch_mmu_flags(mem_map):
    arch_mmu_flags = 0

    if mem_map.type == MEM_MAP_TYPE_CACHED:
        arch_mmu_flags |= ARCH_MMU_FLAG_CACHED
    elif mem_map.type == MEM_MAP_TYPE_UNCACHED:
        arch_mmu_flags |= ARCH_MMU_FLAG_UNCACHED
    elif mem_map.type == MEM_MAP_TYPE_UNCACHED_DEVICE:
        arch_mmu_flags |= ARCH_MMU_FLAG_UNCACHED_DEVICE

    if mem_map.non_secure:
        arch_mmu_flags |= ARCH_MMU_FLAG_NS

    return arch_mmu_flags


def pack_mgmt_flags(mgmt_flags):
    flags = TRUSTY_APP_MGMT_FLAGS_NONE
    if mgmt_flags.restart_on_exit:
        flags |= TRUSTY_APP_MGMT_FLAGS_RESTART_ON_EXIT
    if mgmt_flags.deferred_start:
        flags |= TRUSTY_APP_MGMT_FLAGS_DEFERRED_START
    if mgmt_flags.non_critical_app:
        flags |= TRUSTY_APP_MGMT_FLAGS_NON_CRITICAL_APP

    return flags


def pack_start_port_flags(flags):
    start_port_flags = TRUSTY_APP_MGMT_FLAGS_NONE
    if flags.allow_ta_connect:
        start_port_flags |= IPC_PORT_ALLOW_TA_CONNECT
    if flags.allow_ns_connect:
        start_port_flags |= IPC_PORT_ALLOW_NS_CONNECT

    return start_port_flags


'''
Pack a given string with null padding to make its size
multiple of 4.
packed data includes length + string + null + padding
'''
def pack_inline_string(value):
    size = len(value) + 1
    pad_len = 3 - (size + 3) % 4
    packed = struct.pack("I", size) + value + '\0' + pad_len * '\0'
    assert len(packed) % 4 == 0
    return packed


'''
Creates Packed data from extracted manifest data
Writes the packed data to binary file
'''
def pack_manifest_data(manifest, log):
    # PACK {
    #        uuid, app_name_size, app_name,
    #        TRUSTY_APP_CONFIG_KEY_MIN_HEAP_SIZE, min_heap,
    #        TRUSTY_APP_CONFIG_KEY_MIN_STACK_SIZE, min_stack,
    #        TRUSTY_APP_CONFIG_KEY_MAP_MEM, id, addr, size,
    #        TRUSTY_APP_CONFIG_KEY_MAP_MEM, id, addr, size,
    #        TRUSTY_APP_CONFIG_KEY_MGMT_FLAGS, mgmt_flags
    #        TRUSTY_APP_CONFIG_KEY_START_PORT, flag, name_size, name
    #      }
    out = cStringIO.StringIO()

    uuid = swap_uuid_bytes(manifest.uuid)
    out.write(uuid)

    out.write(pack_inline_string(manifest.app_name))

    if manifest.min_heap is not None:
        out.write(struct.pack("II",TRUSTY_APP_CONFIG_KEY_MIN_HEAP_SIZE,
                              manifest.min_heap))

    if manifest.min_stack is not None:
        out.write(struct.pack("II", TRUSTY_APP_CONFIG_KEY_MIN_STACK_SIZE,
                              manifest.min_stack))

    for memio_map in manifest.mem_io_maps:
        out.write(struct.pack("IIQQI",
                              TRUSTY_APP_CONFIG_KEY_MAP_MEM,
                              memio_map.id,
                              memio_map.addr,
                              memio_map.size,
                              pack_mem_map_arch_mmu_flags(memio_map)))

    if manifest.mgmt_flags is not None:
        out.write(struct.pack("II",
                              TRUSTY_APP_CONFIG_KEY_MGMT_FLAGS,
                              pack_mgmt_flags(manifest.mgmt_flags)))

    for port_entry in manifest.start_ports:
        out.write(struct.pack("II",
                              TRUSTY_APP_CONFIG_KEY_START_PORT,
                              pack_start_port_flags(
                                      port_entry.start_port_flags)))
        out.write(pack_inline_string(port_entry.name))

    return out.getvalue()


'''
Creates manifest JSON string from packed manifest data
'''
def unpack_binary_manifest_to_json(packed_data):
    return manifest_data_to_json(unpack_binary_manifest_to_data(packed_data))


def manifest_data_to_json(manifest):
    return json.dumps(manifest, sort_keys=True, indent=4)


'''
This method can be used for extracting manifest data from packed binary.
UUID should be present in packed data.
'''
def unpack_binary_manifest_to_data(packed_data):
    manifest = {}

    # Extract UUID
    uuid, packed_data = packed_data[:16], packed_data[16:]
    uuid = swap_uuid_bytes(uuid)
    uuid = uuid.encode("hex")
    uuid = uuid[:8] + "-" \
            + uuid[8:12] + "-" \
            + uuid[12:16] + "-" \
            + uuid[16:20] + "-" \
            + uuid[20:]

    manifest[UUID] = uuid

    # Extract APP_NAME
    # read size of the name, this includes a null character
    (name_size,), packed_data = struct.unpack(
            "I", packed_data[:4]), packed_data[4:]
    # read the name without a trailing null character
    manifest[APP_NAME], packed_data = \
            packed_data[:name_size-1], packed_data[name_size-1:]
    # discard trailing null characters
    # it includes trailing null character of a string and null padding
    pad_len = 1 + 3 - (name_size + 3) % 4
    packed_data = packed_data[pad_len:]

    # Extract remaining app configurations
    while len(packed_data) > 0:
        (tag,), packed_data = struct.unpack(
                "I", packed_data[:4]), packed_data[4:]

        if tag == TRUSTY_APP_CONFIG_KEY_MIN_HEAP_SIZE:
            assert MIN_HEAP not in manifest
            (manifest[MIN_HEAP],), packed_data = struct.unpack(
                    "I", packed_data[:4]), packed_data[4:]
        elif tag == TRUSTY_APP_CONFIG_KEY_MIN_STACK_SIZE:
            assert MIN_STACK not in manifest
            (manifest[MIN_STACK],), packed_data = struct.unpack(
                    "I", packed_data[:4]), packed_data[4:]
        elif tag == TRUSTY_APP_CONFIG_KEY_MAP_MEM:
            if MEM_MAP not in manifest:
                manifest[MEM_MAP] = []
            mem_map_entry = {}
            (id_,), packed_data = struct.unpack(
                    "I", packed_data[:4]), packed_data[4:]
            (addr,), packed_data = struct.unpack(
                    "Q", packed_data[:8]), packed_data[8:]
            (size,), packed_data = struct.unpack(
                    "Q", packed_data[:8]), packed_data[8:]
            (arch_mmu_flags,), packed_data = struct.unpack(
                    "I", packed_data[:4]), packed_data[4:]
            mem_map_entry[MEM_MAP_ID] = id_
            mem_map_entry[MEM_MAP_ADDR] = hex(addr)
            mem_map_entry[MEM_MAP_SIZE] = hex(size)
            mem_map_entry[MEM_MAP_TYPE] = {
                    ARCH_MMU_FLAG_CACHED: MEM_MAP_TYPE_CACHED,
                    ARCH_MMU_FLAG_UNCACHED: MEM_MAP_TYPE_UNCACHED,
                    ARCH_MMU_FLAG_UNCACHED_DEVICE: MEM_MAP_TYPE_UNCACHED_DEVICE,
                    }[arch_mmu_flags & ARCH_MMU_FLAG_CACHE_MASK]
            mem_map_entry[MEM_MAP_NON_SECURE] = bool(arch_mmu_flags &
                                                     ARCH_MMU_FLAG_NS)
            manifest[MEM_MAP].append(mem_map_entry)
        elif tag == TRUSTY_APP_CONFIG_KEY_MGMT_FLAGS:
            (flag,), packed_data = struct.unpack(
                    "I", packed_data[:4]), packed_data[4:]
            mgmt_flag = {
                    MGMT_FLAG_RESTART_ON_EXIT: False,
                    MGMT_FLAG_DEFERRED_START: False,
                    MGMT_FLAG_NON_CRITICAL_APP: False
            }
            if flag & TRUSTY_APP_MGMT_FLAGS_RESTART_ON_EXIT:
                mgmt_flag[MGMT_FLAG_RESTART_ON_EXIT] = True
            if flag &  TRUSTY_APP_MGMT_FLAGS_DEFERRED_START:
                mgmt_flag[MGMT_FLAG_DEFERRED_START] = True
            if flag & TRUSTY_APP_MGMT_FLAGS_NON_CRITICAL_APP:
                mgmt_flag[MGMT_FLAG_NON_CRITICAL_APP] = True
            manifest[MGMT_FLAGS] = mgmt_flag
        elif tag == TRUSTY_APP_CONFIG_KEY_START_PORT:
            if START_PORTS not in manifest:
                manifest[START_PORTS] = []
            start_port_entry = {}

            (flag,), packed_data = struct.unpack(
                    "I", packed_data[:4]), packed_data[4:]

            # read size of the name, this includes a null character
            (name_size,), packed_data = struct.unpack(
                    "I", packed_data[:4]), packed_data[4:]
            # read the name without a trailing null character
            start_port_entry[START_PORT_NAME], packed_data = \
                    packed_data[:name_size-1], packed_data[name_size-1:]
            # discard trailing null characters
            # it includes trailing null character of a string and null padding
            pad_len = 1 + 3 - (name_size + 3) % 4
            packed_data = packed_data[pad_len:]

            start_port_flags = {
                    START_PORT_ALLOW_TA_CONNECT: False,
                    START_PORT_ALLOW_NS_CONNECT: False
            }
            if flag & IPC_PORT_ALLOW_TA_CONNECT:
                start_port_flags[START_PORT_ALLOW_TA_CONNECT] = True
            if flag & IPC_PORT_ALLOW_NS_CONNECT:
                start_port_flags[IPC_PORT_ALLOW_NS_CONNECT] = True
            start_port_entry[START_PORT_FLAGS] = start_port_flags

            manifest[START_PORTS].append(start_port_entry)
        else:
            raise Exception("Unknown tag: {}".format(tag))

    return manifest


def write_packed_data_to_bin_file(packed_data, output_file, log):
    # Write packed data to binary file
    try:
        with open(output_file, "wb") as out_file:
            out_file.write(packed_data)
            out_file.close()
    except IOError as ex:
        log.error(
                "Unable to write to output file: {}"
                .format(output_file) + "\n" + str(ex))


def read_json_config_file(input_file, log):
    try:
       read_file = open(input_file, "r")
    except IOError as ex:
        log.error(
                "Unable to open input file: {}"
                .format(input_file) + "\n" + str(ex))
        return None

    try:
        manifest_dict = json.load(read_file)
        return manifest_dict
    except ValueError as ex:
        log.error(
                "Unable to parse config JSON - {}"
                .format(str(ex)))
        return None


def read_config_constants(const_config_files, log):
    const_configs_list = []
    for const_file in const_config_files:
        const_configs_list.append(read_json_config_file(const_file, log))

    return const_configs_list


def define_integer_const_entry(const, log):
    text = hex(const.value) if const.hex_num else str(const.value)
    if const.unsigned:
        text += "U"

    return "#define {} ({})\n".format(const.name, text)


def define_string_const_entry(const, log):
    return "#define {} {}\n".format(const.name, json.dumps(const.value))


def define_bool_const_entry(const, log):
    return "#define {} ({})\n".format(const.name, json.dumps(const.value))


def define_uuid_const_entry(const, log):
    uuid = const.value.encode("hex")

    part = ", ".join(
            ["0x" + uuid[index:index+2] for index in range(16, len(uuid), 2)])

    value = "{{0x{}, 0x{}, 0x{}, {{ {} }}}}\n".format(
            uuid[:8], uuid[8:12], uuid[12:16], part)

    return "#define {} {}".format(const.name, value)


def create_header_entry(constant, log):
    if constant.type == CONST_PORT:
        return define_string_const_entry(constant, log)
    elif constant.type == CONST_UUID:
        return define_uuid_const_entry(constant, log)
    elif constant.type == CONST_INT:
        return define_integer_const_entry(constant, log)
    elif constant.type == CONST_BOOL:
        return define_bool_const_entry(constant, log)
    else:
        raise Exception("Unknown tag: {}".format(const_type))


'''
Writes given constants to header file in given header directory.
'''
def write_consts_to_header_file(const_config, header_dir, log):
    # Construct header file path
    header_file = os.path.join(header_dir, const_config.header)
    # Check whether the output directory of header file exist
    # If it not exists create it.
    dir_name = os.path.dirname(header_file)
    if dir_name and not os.path.exists(dir_name):
        os.makedirs(dir_name)

    try:
        with open(header_file, "w") as out_file:
            out_file.write("#pragma once\n")
            out_file.write("#include <stdbool.h>\n\n")
            for const in const_config.constants:
                header_entries = create_header_entry(const, log)
                out_file.write(header_entries)
    except IOError as ex:
        log.error(
                "Unable to write to header file: {}"
                .format(header_file) + "\n" + str(ex))


'''
Parse a give JSON constant data structure
'''
def parse_constant(constant, log):
    const_type = get_string(constant, CONST_TYPE, {}, log)
    if const_type is None:
        return None

    name = get_string(constant, CONST_NAME, {}, log)
    if const_type == CONST_PORT:
        value = get_string(constant, CONST_VALUE, {}, log)
        return Constant(name, value, const_type)
    elif const_type == CONST_UUID:
        value = get_string(constant, CONST_VALUE, {}, log)
        return Constant(name, parse_uuid(value, log), const_type)
    elif const_type == CONST_INT:
        unsigned = get_boolean(constant, CONST_UNSIGNED, {}, log)
        text_value = constant.get(CONST_VALUE)
        hex_num = isinstance(text_value, basestring) and \
                text_value.startswith("0x")
        value = get_int(constant, CONST_VALUE, {}, log)
        return Constant(name, value, const_type, unsigned, hex_num)
    elif const_type == CONST_BOOL:
        value = get_boolean(constant, CONST_VALUE, {}, log)
        return Constant(name, value, const_type)
    else:
        log.error("Unknown constant type: {}".format(const_type))


'''
Parse a given JSON constant-config data structure containing
a header and list of constants
'''
def parse_config_constant(const_config, log):
    header_file = get_string(const_config, HEADER, {}, log)

    const_list = get_list(const_config, CONSTANTS, log, optional=False,
                          default=[])

    constants = []
    for item in const_list:
        item = coerce_to_dict(item, CONSTANTS, log)
        if item is None:
            continue
        constants.append(parse_constant(item, log))
        if item:
            log.error("Unknown atributes in constant: {} "
                      .format(item))

    if const_config:
        log.error("Unknown atributes in constants config: {} "
                  .format(const_config))

    return ConfigConstants(constants, header_file)


'''
Collects ConfigConstant(s) from list of JSON config constants data
'''
def extract_config_constants(config_consts_list, log):
    config_constants = []

    for config_const in config_consts_list:
        config_constants.append(parse_config_constant(config_const, log))

    return config_constants


'''
Parse JSON config constants and creates separate header files with constants
for each JSON config
'''
def process_config_constants(const_config_files, header_dir, log):
    if const_config_files is None:
        return []

    config_consts_list = read_config_constants(const_config_files, log)
    if log.error_occurred():
        return []

    config_constants = extract_config_constants(config_consts_list, log)
    if log.error_occurred():
        return []

    # generate header files
    for const_config in config_constants:
        write_consts_to_header_file(const_config, header_dir, log)

    return config_constants


def index_constants(config_constants, log):
    constants = {}
    for const_config in config_constants:
        for const in const_config.constants:
            constants[const.name] = const

    return constants


'''
START OF THE PROGRAM
Handles the command line arguments
Parses the given manifest input file and creates packed data
Writes the packed data to binary output file.
'''
def main(argv):
    parser = argparse.ArgumentParser();
    parser.add_argument(
            "-i", "--input",
            dest="input_filename",
            required=True,
            type=str,
            help="It should be trust app manifest config JSON file"
    )
    parser.add_argument(
            "-o", "--output",
            dest="output_filename",
            required=True,
            type=str,
            help="It will be binary file with packed manifest data"
    )
    parser.add_argument(
            "-c", "--constants",
            dest="constants",
            required=False,
            action="append",
            help="JSON file with manifest config constants"
    )
    parser.add_argument(
            "--header-dir",
            dest="header_dir",
            required=False,
            type=str,
            help="Directory path for generating headers"
    )
    # Parse the command line arguments
    args = parser.parse_args()
    if args.constants and not args.header_dir:
        args.error("--header-dir is required if --constants are specified")

    log = Log()

    # collect config constants and create header files for each const config
    config_constants = process_config_constants(args.constants,
                                                args.header_dir, log)
    if log.error_occurred():
        return 1
    constants = index_constants(config_constants, log)

    if not os.path.exists(args.input_filename):
        log.error(
                "Manifest config JSON file doesn't exist: {}"
                .format(args.input_filename))
        return 1

    manifest_dict = read_json_config_file(args.input_filename, log)
    if log.error_occurred():
        return 1

    # By default app directory name will be used as app-name
    default_app_name = os.path.basename(os.path.dirname(args.input_filename))

    # parse the manifest config
    manifest = parse_manifest_config(manifest_dict, constants, default_app_name,
                                     log)
    if log.error_occurred():
        return 1

    # Pack the data as per c structures
    packed_data = pack_manifest_data(manifest, log)
    if log.error_occurred():
        return 1

    # Write to file.
    write_packed_data_to_bin_file(packed_data, args.output_filename, log)
    if log.error_occurred():
        return 1

    return 0


if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
