# !/usr/bin/env python
###############################################################################
# Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
###############################################################################

###############################################################################
# FILE: intermediate_layer.py
#
# DESCRIPTION: Creates an intermediate json file with information provided
#              by the configuration json file, dwarf signatures and trace
#              files.
#
###############################################################################

import os
import re
import glob
import argparse
import subprocess
import json
from argparse import RawTextHelpFormatter
import cc_logger
import time
from typing import Dict
from typing import List
from typing import Generator
from typing import Union
from typing import Tuple
import logging

__version__ = "7.0"

# Static map that defines the elf file source type in the intermediate json
ELF_MAP = {
    "bl1": 0,
    "bl2": 1,
    "bl31": 2,
    "bl32": 3,
    "scp_ram": 10,
    "scp_rom": 11,
    "mcp_rom": 12,
    "mcp_ram": 13,
    "secure_hafnium": 14,
    "hafium": 15,
    "custom_offset": 100
}


def os_command(command, show_command=False):
    """
    Function that execute an os command, on fail exit the program

    :param command: OS command as string
    :param show_command: Optional argument to print the command in stdout
    :return: The string output of the os command
    """
    try:
        if show_command:
            print("OS command: {}".format(command))
        out = subprocess.check_output(
            command, stderr=subprocess.STDOUT, shell=True)
    except subprocess.CalledProcessError as ex:
        raise Exception(
            "Exception running command '{}': {}({})".format(
                command, ex.output, ex.returncode))
    return out.decode("utf8")


def load_stats_from_traces(trace_globs):
    """
    Function to process and consolidate statistics from trace files

    :param trace_globs: List of trace file patterns
    :return: Dictionary with stats from trace files i.e.
        {mem address in decimal}=(times executed, inst size)
    """
    stats = {}
    stat_size = {}

    # Make a list of unique trace files
    trace_files = []
    for tg in trace_globs:
        trace_files.extend(glob.glob(tg))
    trace_files = set(trace_files)

    if not trace_files:
        raise Exception("No trace files found for '{}'".format(trace_globs))
    # Load stats from the trace files
    for trace_file in trace_files:
        try:
            with open(trace_file, 'r') as f:
                for line in f:
                    data = line.split()
                    address = int(data[0], 16)
                    stat = int(data[1])
                    size = int(data[2])
                    stat_size[address] = size
                    if address in stats:
                        stats[address] += stat
                    else:
                        stats[address] = stat
        except Exception as ex:
            logger.error("@Loading stats from trace files:{}".format(ex))
    # Merge the two dicts
    for address in stats:
        stats[address] = (stats[address], stat_size[address])
    return stats


def get_code_sections_for_binary(elf_name):
    """
    Function to return the ranges of memory address for sections of code
    in the elf file

    :param elf_name: Elf binary file name
    :return: List of code sections tuples, i.e. (section type, initial
            address, end address)
    """
    command = """%s -h %s | grep -B 1 CODE | grep -v CODE \
                | awk '{print $2" "$4" "$3}'""" % (OBJDUMP, elf_name)
    text_out = os_command(command)
    sections = text_out.split('\n')
    sections.pop()
    secs = []
    for sec in sections:
        try:
            d = sec.split()
            secs.append((d[0], int(d[1], 16), int(d[2], 16)))
        except Exception as ex:
            logger.error(
                "@Returning memory address code sections:".format(ex))
    return secs


def get_executable_ranges_for_binary(elf_name):
    """
    Get function ranges from an elf file

    :param elf_name: Elf binary file name
    :return: List of tuples for ranges i.e. (range start, range end)
    """
    # Parse all $x / $d symbols
    symbol_table = []
    address = None
    _type = None
    command = r"""%s -s %s | awk '/\$[xatd]/ {print $2" "$8}'""" % (
        READELF, elf_name)
    text_out = os_command(command)
    lines = text_out.split('\n')
    lines.pop()
    for line in lines:
        try:
            data = line.split()
            address = int(data[0], 16)
            _type = 'X' if data[1] in ['$x', '$t', '$a'] else 'D'
        except Exception as ex:
            logger.error("@Getting executable ranges:".format(ex))
        symbol_table.append((address, _type))

    # Add markers for end of code sections
    sections = get_code_sections_for_binary(elf_name)
    for sec in sections:
        symbol_table.append((sec[1] + sec[2], 'S'))

    # Sort by address
    symbol_table = sorted(symbol_table, key=lambda tup: tup[0])

    # Create ranges (list of START/END tuples)
    ranges = []
    range_start = symbol_table[0][0]
    rtype = symbol_table[0][1]
    for sym in symbol_table:
        if sym[1] != rtype:
            if rtype == 'X':
                # Subtract one because the first address of the
                # next range belongs to the next range.
                ranges.append((range_start, sym[0] - 1))
            range_start = sym[0]
            rtype = sym[1]
    return ranges


def remove_workspace(path, workspace):
    """
    Get the relative path to a given workspace

    :param path: Path relative to the workspace to be returned
    :param workspace: Path.
    """
    ret = path if workspace is None else os.path.relpath(path, workspace)
    return ret


def get_function_line_numbers(source_file: str) -> Dict[str, int]:
    """
    Using ctags get all the function names with their line numbers
    within the source_file

    :return: Dictionary with function name as key and line number as value
    """
    command = "ctags -x --c-kinds=f {}".format(source_file)
    fln = {}
    try:
        function_lines = os_command(command).split("\n")
        for line in function_lines:
            cols = line.split()
            if len(cols) < 3:
                continue
            if cols[1] == "function":
                fln[cols[0]] = int(cols[2])
            elif cols[1] == "label":
                if cols[0] == "func":
                    fln[cols[-1]] = int(cols[2])
                elif cols[0] + ":" == cols[-1]:
                    fln[cols[0]] = int(cols[2])
    except BaseException:
        logger.warning("Warning: Can't get all function line numbers from %s" %
                       source_file)
    except Exception as ex:
        logger.warning(f"Warning: Unknown error '{ex}' when executing command "
                       f"'{command}'")
        return {}
    return fln


class FunctionLineNumbers(object):
    """Helper class used to get a function start line number within
     a source code file"""

    def __init__(self, workspace: str):
        """
        Initialise dictionary to allocate source code files with the
        corresponding function start line numbers.

        :param workspace: The folder where the source files are deployed
        """
        self.filenames = {}
        self.workspace = workspace

    def get_line_number(self, filename: str, function_name: str) -> int:
        if not FUNCTION_LINES_ENABLED:
            return 0
        if filename not in self.filenames:
            source_file = os.path.join(self.workspace, filename)
            # Get all functions with their lines in the source file
            self.filenames[filename] = get_function_line_numbers(source_file)
        return 0 if function_name not in self.filenames[filename] else \
            self.filenames[filename][function_name]


class BinaryParser(object):
    """Class used to create an instance to parse the binary files with a
    dwarf signature in order to produce logical information to be matched with
    traces and produce a code coverage report"""

    def __init__(self, dump: str, _workspace: str, _remove_workspace: bool,
                 local_workspace: str):
        """
        Initialisation of the instance to parse binary files.

        :param dump: Binary dump (string) containing assembly code and source
        code metadata, i.e. source code location and line number.
        :param _workspace: Workspace (folder) where the source files were
        built from.
        :param _remove_workspace: Boolean to indicate if the build of
        source files was local (false) or from a CI (true).
        :param local_workspace: Path to the local workspace where the source
        files reside
        """
        self.dump = dump
        self.no_source_functions = self.get_no_source_functions()
        self.workspace = _workspace
        self.remove_workspace = _remove_workspace
        self.local_workspace = local_workspace
        self.function_line_numbers = FunctionLineNumbers(self.local_workspace)

    def get_no_source_functions(self) -> Dict[int, Dict]:
        """Find in the dwarf dump all the functions with no source code i.e.:
        function_name():
               start_hex_address opcode
               ....
               end_hex_address opcode

        :returns: Dictionary of functions indexed by start address function's
        location
        """
        # The functions dict is [start_dec_address]={function name, function
        # end address in decimal}
        _functions = {}
        groups = re.findall(r"(.+?)\(\):\n\s+([a-f0-9]+):."
                            r"+?\n(\s+([a-f0-9]+):.+?\n)*", self.dump)
        for group in groups:
            function_name, start_hex_address, _, end_hex_address = group
            if not end_hex_address:
                end_hex_address = start_hex_address
            _functions[int(start_hex_address, 16)] = {'name': function_name,
                                                      'end_address': int(
                                                          end_hex_address, 16)}
        return _functions

    class SourceCodeBlock(object):
        """Class used to represent a source code block of information within
        a function block in a binary dump file.
        The source code block contains the following components:
        - Source code file that contains the source code corresponding
        to the assembly code.
        - Line number within the source code file corresponding to the source
        code.
        - Assembly code block.
        """

        def __init__(self, source_code_block_dump):
            """
            Create an instance of a source code block within a function block.

            :param source_code_block: Tuple of 3 elements that contains the
            components of a source code block.
            """
            self.source_file, self.line_number, self.asm_code \
                = source_code_block_dump

        @staticmethod
        def get(dwarf_data: str) -> Generator['BinaryParser.SourceCodeBlock',
                                              None, None]:
            source_block_groups = re.findall(r"(?s)(/[a-zA-Z_0-9][^\n]+?):"
                                             r"([0-9]+)(?: [^\n]+)?\n(.+?)"
                                             r"\n(?=/[a-zA-Z_0-9][^\n]+?"
                                             r":[0-9]+[^\n]+?\n|\n$)",
                                             dwarf_data)
            for source_block_group in source_block_groups:
                if len(source_block_group) != 3:
                    logger.warning(f"Source code incomplete:"
                                   f"{source_block_group}")
                    continue
                source_block_dump = list(source_block_group)
                source_block_dump[-1] += "\n\n"  # For parsing assembly lines
                yield BinaryParser.SourceCodeBlock(source_block_dump)

        def __str__(self):
            return f"'{self.source_file}:{self.line_number}'"

    class FunctionBlock(object):
        """Class used to parse and obtain a function block from the
        binary dump file that corresponds to a function declaration in the
        source code file and a block of assembly code mixed with corresponding
        source code lines, i.e. dwarf information.
        The function block has the following components:
        - Function name at source code.
        - DWARF data.
        - Function declaration's line number at source code.
        This comes from dump blocks like these:
        0000000000000230 <_setup>:
        read_el(): <---- Function name at source code
        /home/user/aarch64/setup.c:238 <------ Source file and line number
        230:	d53e1100 	mrs	x0, scr_el3   <----- Assembly lines belonging to
        the source code
        no_setup():
        /home/user/no_setup.c:618
        234:	b2760000 	orr	x0, x0, #0x400
        """

        def __init__(self, function_group: List[str]):
            """
            Create an instance of a function block within a binary dump.

            :param function_group: List containing the function name and
            dwarf data of the block.
            """
            self.name, self.dwarf = function_group
            # Now obtain the function's source file
            m = re.search(r"(/.+?):([0-9]+)(?: [^\n]+)?\n", self.dwarf)
            self.source_file = m.groups()[0].strip() \
                if m and len(m.groups()) == 2 else None
            # Computed later
            self.function_line_number = None

        @staticmethod
        def get(dump: str) -> Generator['BinaryParser.FunctionBlock', None,
                                        None]:
            """
            Static method generator to extract a function block from the binary
            dump.

            :param dump: Binary dump (string) that contains the binary file
            information.
            :return: A FunctionBlock object that is a logical representation
            of a function declaration within the binary dump.
            """
            function_groups = re.findall(r"(?s)([a-zA-Z0-9_]+?)\(\):"
                                         r"\n(/.+?:[0-9]+?.+?)\n"
                                         r"(?=[a-zA-Z0-9_]+?\(\):\n|\n\n$)",
                                         dump)
            for group in function_groups:
                if len(group) != 2:
                    continue
                function_group = list(group)
                function_group[-1] += "\n\n"  # For parsing source code blocks
                yield BinaryParser.FunctionBlock(function_group)

        @property
        def values(self):
            return self.name, self.source_file, self.function_line_number

        def __str__(self):
            return f"'{self.name}:{self.function_line_number}'"

    class AssemblyLine(object):
        """Class used to represent an assembly code line within an
        assembly code block.
        The assembly line instruction is formed by the following components:
        - Hexadecimal address of the assembly instruction.
        - Assembly instruction.
        """

        def __init__(self, line):
            """
            Create an instance representing an assembly code line within an
            assembly code block.

            :param line: Tuple of 2 elements [Hexadecimal number,
            and assembly code]
            """
            self.hex_line_number, self.opcode = line
            self.dec_address = int(self.hex_line_number, 16)
            self.times_executed = 0

        @staticmethod
        def get(asm_code: str) -> Generator['BinaryParser.AssemblyLine',
                                            None, None]:
            """
            Static method generator to extract an assembly code line from an
            assembly code block.

            :param asm_code: Lines of assembly code within the dump
            :return: AssemblyLine object.
            """
            lines = re.findall(r"^\s+([a-fA-F0-9]+):\t(.+?)\n", asm_code,
                               re.DOTALL | re.MULTILINE)
            for line in lines:
                if len(line) != 2:
                    logger.warning(f"Assembly code incomplete: {line}")
                    continue
                yield BinaryParser.AssemblyLine(line)

    @staticmethod
    def get_asm_line(source_code_block: 'BinaryParser.SourceCodeBlock',
                     traces_stats) -> \
            Generator['BinaryParser.AssemblyLine', None, None]:
        """Generator method to obtain all assembly line codes within a source
        code line """
        traces_stats = traces_stats
        for asm_line in BinaryParser.AssemblyLine.get(
                source_code_block.asm_code):
            asm_line.times_executed = traces_stats.get(asm_line.dec_address,
                                                       [0])[0]
            yield asm_line

    def get_source_code_block(self, function_block: FunctionBlock) -> \
            Generator['BinaryParser.SourceCodeBlock', None, None]:
        """
        Generator method to obtain all the source code blocks within a
        function block.

        :param function_block: FunctionBlock object that contains the code
        the source code blocks.
        :return: A SourceCodeBlock object.
        """
        for source_code_block in BinaryParser.SourceCodeBlock.get(
                function_block.dwarf):
            if self.remove_workspace:
                source_code_block.source_file = remove_workspace(
                    source_code_block.source_file, self.workspace)
            yield source_code_block

    def get_function_block(self) -> Generator['BinaryParser.FunctionBlock',
                                              None, None]:
        """Generator method to obtain all the function blocks contained in
        the binary dump file.
        """
        for function_block in BinaryParser.FunctionBlock.get(self.dump):
            if function_block.source_file is None:
                logger.warning(f"Source file not found for function "
                               f"{function_block.name}, will not be covered")
                continue
            if self.remove_workspace:
                function_block.source_file = remove_workspace(
                    function_block.source_file, self.workspace)
            function_block.function_line_number = \
                self.function_line_numbers.get_line_number(
                    function_block.source_file, function_block.name)
            yield function_block


class CoverageHandler(object):
    """ Class used to handle source files coverage linked with their functions
    and line code coverage from function blocks obtained from DWARF data and
    trace code coverage from CC plugin"""

    def __init__(self):
        self._source_files = {}

    def add_function_coverage(self, function_data:
                              Union[BinaryParser.FunctionBlock,
                                    Tuple[str, str, int]]):
        """ Add a function coverage block and a source file coverage block,
        if not already created and link them"""
        # Unpack function data either as an FunctionBlock object property or a
        # tuple
        name, source_file, function_line_number = function_data.values if \
            isinstance(function_data, BinaryParser.FunctionBlock) else \
            function_data

        # Add source file coverage block it if not already there
        self._source_files.setdefault(source_file,
                                      {"functions": {}, "lines": {}})
        # Add a function coverage block (if not existent) from a function
        # block using the function block name as key and link it to the source
        # file coverage block
        self._source_files[source_file]["functions"].setdefault(
            name, {"covered": False, "line_number": function_line_number})

    def add_line_coverage(self, source_code_block:
                          BinaryParser.SourceCodeBlock):
        """ Add a line coverage block and a source file coverage block,
        if not already created and link them"""
        # Add source file coverage block it if not already there
        self._source_files.setdefault(source_code_block.source_file,
                                      {"functions": {}, "lines": {}})
        # Add a line coverage block (if not existent) from a source block
        # using the source code line number as a key and link it to the source
        # file coverage block
        self._source_files[source_code_block.source_file]["lines"].setdefault(
            source_code_block.line_number, {"covered": False, "elf_index": {}})

    def add_asm_line(self, source_code_block: BinaryParser.SourceCodeBlock,
                     asm_line: BinaryParser.AssemblyLine, elf_index: int):
        """Add an assembly line from the DWARF data linked to a source code
        line"""
        self._source_files[source_code_block.source_file]["lines"][
            source_code_block.line_number]["elf_index"].setdefault(
            elf_index, {})
        self._source_files[source_code_block.source_file]["lines"][
            source_code_block.line_number]["elf_index"][
            elf_index].setdefault(asm_line.dec_address,
                                  (asm_line.opcode, asm_line.times_executed))

    def set_line_coverage(self, source_code_block:
                          BinaryParser.SourceCodeBlock, value: bool):
        self._source_files[source_code_block.source_file]["lines"][
            source_code_block.line_number]["covered"] = value

    def set_function_coverage(self, function_block:
                              Union[BinaryParser.FunctionBlock,
                                    Tuple[str, str]], value: bool):
        name, source_file = (function_block.name, function_block.source_file)\
            if isinstance(function_block, BinaryParser.FunctionBlock) else \
            function_block
        self._source_files[source_file]["functions"][name]["covered"] = value

    @property
    def source_files(self):
        return self._source_files


class IntermediateCodeCoverage(object):
    """Class used to process the trace data along with the dwarf
    signature files to produce an intermediate layer in json with
    code coverage in assembly and c source code.
    """

    def __init__(self, _config, local_workspace):
        self._data = {}
        self.config = _config
        self.workspace = self.config['parameters']['workspace']
        self.remove_workspace = self.config['configuration']['remove_workspace']
        self.local_workspace = local_workspace
        self.elfs = self.config['elfs']
        # Dictionary with stats from trace files {address}=(times executed,
        # inst size)
        self.traces_stats = {}
        # Dictionary of unique assembly line memory address against source
        # file location
        # {assembly address} = (opcode, source file location, line number in
        # the source file, times executed)
        self.asm_lines = {}
        # Dictionary of {source file location}=>{'lines': {'covered':Boolean,
        # 'elf_index'; {elf index}=>{assembly address}=>(opcode,
        # times executed),
        # 'functions': {function name}=>is covered(boolean)}
        self.coverage = CoverageHandler()
        self.functions = []
        # Unique set of elf list of files
        self.elf_map = {}
        # For elf custom mappings
        self.elf_custom = None

    def process(self):
        """
        Public method to process the trace files and dwarf signatures
        using the information contained in the json configuration file.
        This method writes the intermediate json file output linking
        the trace data and c source and assembly code.
        """
        self.asm_lines = {}
        # Initialize for unknown elf files
        self.elf_custom = ELF_MAP["custom_offset"]
        print("Generating intermediate json layer '{}'...".format(
            self.config['parameters']['output_file']))
        for elf in self.elfs:
            # Gather information
            elf_name = elf['name']
            # Obtain trace data
            self.traces_stats = load_stats_from_traces(elf['traces'])
            # Produce code coverage
            self._process_binary(elf_name)
            # Write to the intermediate json file
        data = {"source_files": self.coverage.source_files,
                "configuration": {
                    "sources": self.config['parameters']['sources'],
                    "metadata": "" if 'metadata' not in
                                      self.config['parameters'] else
                    self.config['parameters']['metadata'],
                    "elf_map": self.elf_map}
                }
        json_data = json.dumps(data, indent=4, sort_keys=True)
        with open(self.config['parameters']['output_file'], "w") as f:
            f.write(json_data)

    def get_elf_index(self, elf_name: str) -> int:
        """Obtains the elf index and fills the elf_map instance variable"""
        if elf_name not in self.elf_map:
            if elf_name in ELF_MAP:
                self.elf_map[elf_name] = ELF_MAP[elf_name]
            else:
                self.elf_map[elf_name] = ELF_MAP["custom_offset"]
                ELF_MAP["custom_offset"] += 1
        return self.elf_map[elf_name]

    def _process_binary(self, elf_filename: str) -> BinaryParser:
        """
        Process an elf file i.e. match the source code and asm lines against
        trace files (coverage).

        :param elf_filename: Elf binary file name
        """
        command = "%s -Sl %s | tee %s" % (OBJDUMP, elf_filename,
                                          elf_filename.replace(".elf", ".dump"))
        dump = os_command(command, show_command=True)
        # with open(elf_filename.replace(".elf", ".dump"), "r") as f:
        #    dump = f.read()
        dump += "\n\n"  # For pattern matching the last function
        logger.info(f"Parsing assembly file {elf_filename}")
        elf_name = os.path.splitext(os.path.basename(elf_filename))[0]
        elf_index = self.get_elf_index(elf_name)
        parser = BinaryParser(dump, self.workspace, self.remove_workspace,
                              self.local_workspace)
        total_number_functions = 0
        functions_covered = 0
        for function_block in parser.get_function_block():
            total_number_functions += 1
            # Function contains source code
            self.coverage.add_function_coverage(function_block)
            is_function_covered = False
            for source_code_block in parser.get_source_code_block(
                    function_block):
                self.coverage.add_line_coverage(source_code_block)
                is_line_covered = False
                for asm_line in parser.get_asm_line(source_code_block,
                                                    self.traces_stats):
                    # Here it is checked the line coverage
                    is_line_covered = asm_line.times_executed > 0 or \
                                      is_line_covered
                    self.coverage.add_asm_line(source_code_block, asm_line,
                                               elf_index)
                logger.debug(f"Source file {source_code_block} is "
                             f"{'' if is_line_covered else 'not '}covered")
                if is_line_covered:
                    self.coverage.set_line_coverage(source_code_block, True)
                    is_function_covered = True
            logger.debug(f"\tFunction '{function_block.name}' at '"
                         f"{function_block.source_file} is "
                         f"{'' if is_function_covered else 'not '}covered")
            if is_function_covered:
                self.coverage.set_function_coverage(function_block, True)
                functions_covered += 1
        logger.info(f"Total functions: {total_number_functions}, Functions "
                    f"covered:{functions_covered}")
        # Now check code coverage in the functions with no dwarf signature
        self._process_fn_no_sources(parser)
        return parser

    def _process_fn_no_sources(self, parser: BinaryParser):
        """
        Checks function coverage for functions with no dwarf signature i.e.
         sources.

        :param parser: Binary parser that contains objects needed
        to check function line numbers including the dictionary of functions
        to be checked i.e [start_dec_address]={'name', 'end_address'}
        """
        if not FUNCTION_LINES_ENABLED:
            return  # No source code at the workspace
        traces_addresses = sorted(self.traces_stats.keys())
        traces_address_pointer = 0
        _functions = parser.no_source_functions
        functions_addresses = sorted(_functions.keys())
        address_size = 4
        for start_address in functions_addresses:
            function_covered = False
            function_name = _functions[start_address]['name']
            # Get all files in the source code where the function is defined
            source_files = os_command("grep --include '*.c' --include '*.s' "
                                      "--include '*.S' -nrw '{}' {}"
                                      "| cut -d: -f1".
                                      format(function_name,
                                             self.local_workspace))
            unique_files = set(source_files.split())
            sources_found = []
            for source_file in unique_files:
                line_number = parser.function_line_numbers.get_line_number(
                    source_file, function_name)
                if line_number > 0:
                    sources_found.append((source_file, line_number))
            if len(sources_found) == 0:
                logger.debug(f"'{function_name}' not found in sources")
            elif len(sources_found) > 1:
                logger.warning(f"'{function_name}' declared in "
                               f"{len(sources_found)} files")
            else:
                source_file_found, function_line_number = sources_found[0]
                function_source_file = remove_workspace(source_file_found,
                                                        self.local_workspace)
                self.coverage.add_function_coverage((function_name,
                                                     function_source_file,
                                                     function_line_number))
                for in_function_address in \
                        range(start_address,
                              _functions[start_address]['end_address']
                              + address_size, address_size):
                    if in_function_address in traces_addresses[
                                              traces_address_pointer:]:
                        function_covered = True
                        traces_address_pointer = traces_addresses.index(
                            in_function_address) + 1
                        break
                logger.info(f"Added non-sources function '{function_name}' "
                            f"with coverage: {function_covered}")
                if function_covered:
                    self.coverage.set_function_coverage((function_name,
                                                         function_source_file),
                                                        function_covered)


json_conf_help = """
Produces an intermediate json layer for code coverage reporting
using an input json configuration file.

Input json configuration file format:
{
    "configuration":
        {
        "remove_workspace": <true if 'workspace' must be from removed from the
                                path of the source files>,
        "include_assembly": <true to include assembly source code in the
                            intermediate layer>
        },
    "parameters":
        {
        "objdump": "<Path to the objdump binary to handle dwarf signatures>",
        "readelf: "<Path to the readelf binary to handle dwarf signatures>",
        "sources": [ <List of source code origins, one or more of the next
                        options>
                    {
                    "type": "git",
                    "URL":  "<URL git repo>",
                    "COMMIT": "<Commit id>",
                    "REFSPEC": "<Refspec>",
                    "LOCATION": "<Folder within 'workspace' where this source
                                is located>"
                    },
                    {
                    "type": "http",
                    "URL":  <URL link to file>",
                    "COMPRESSION": "xz",
                    "LOCATION": "<Folder within 'workspace' where this source
                                is located>"
                    }
                ],
        "workspace": "<Workspace folder where the source code was located to
                        produce the elf/axf files>",
        "output_file": "<Intermediate layer output file name and location>",
        "metadata": {<Metadata objects to be passed to the intermediate json
                    files>}
        },
    "elfs": [ <List of elf files to be traced/parsed>
            {
                    "name": "<Full path name to elf/axf file>",
                    "traces": [ <List of trace files to be parsed for this
                                elf/axf file>
                                "Full path name to the trace file,"
                              ]
                }
        ]
}
"""
OBJDUMP = None
READELF = None
FUNCTION_LINES_ENABLED = None


def main():
    global OBJDUMP
    global READELF
    global FUNCTION_LINES_ENABLED

    parser = argparse.ArgumentParser(epilog=json_conf_help,
                                     formatter_class=RawTextHelpFormatter)
    parser.add_argument('--config-json', metavar='PATH',
                        dest="config_json", default='config_file.json',
                        help='JSON configuration file', required=True)
    parser.add_argument('--local-workspace', default="",
                        help=('Local workspace folder where source code files'
                              ' and folders resides'))
    args = parser.parse_args()
    try:
        with open(args.config_json, 'r') as f:
            config = json.load(f)
    except Exception as ex:
        print("Error at opening and processing JSON: {}".format(ex))
        return
    print(json.dumps(config, indent=4))
    # Setting toolchain binary tools variables
    OBJDUMP = config['parameters']['objdump']
    READELF = config['parameters']['readelf']
    # Checking if are installed
    os_command("{} --version".format(OBJDUMP))
    os_command("{} --version".format(READELF))

    if args.local_workspace != "":
        # Checking ctags installed
        try:
            os_command("ctags --version")
        except BaseException:
            print("Warning!: ctags not installed/working function line numbers\
                    will be set to 0. [{}]".format(
                "sudo apt install exuberant-ctags"))
        else:
            FUNCTION_LINES_ENABLED = True

    intermediate_layer = IntermediateCodeCoverage(config, args.local_workspace)
    intermediate_layer.process()


if __name__ == '__main__':
    logger = cc_logger.logger
    start_time = time.time()
    main()
    elapsed_time = time.time() - start_time
    print("Elapsed time: {}s".format(elapsed_time))
