#!/usr/bin/env python3

r"""
This script will parse error log yaml file(s) and generate
a header file which will then be used by the error logging client and
server to collect and validate the error information generated by the
openbmc software components.

This code uses a mako template to provide the basic template of the header
file we're going to generate.  We then call it with information from the
yaml to generate the header file.
"""

from mako.template import Template
from optparse import OptionParser
import yaml
import sys
import os


def order_inherited_errors(i_errors, i_parents):
    # the ordered list of errors
    errors = list()
    has_inheritance = False
    for error in i_errors:
        if(i_parents[error] is not None):
            has_inheritance = True
            break

    if(has_inheritance):
        # Order the error codes list such that an error is never placed
        # before it's parent. This way generated code can ensure parent
        # definitions precede child error definitions.
        while(len(errors) < len(i_errors)):
            for error in i_errors:
                if(error in errors):
                    # already ordererd
                    continue
                if((not i_parents[error]) or (i_parents[error] in errors)):
                    # parent present, or has no parent, either way this error
                    # can be added
                    errors.append(error)
    else:
        # no inherited errors
        errors = i_errors

    return errors


def check_error_inheritance(i_errors, i_parents):
    for error in i_errors:
        if(i_parents[error] and (i_parents[error] not in i_errors)):
            print(error + " inherits " + i_parents[error] +
                  " but the latter is not defined")
            return False
    return True


# Return the yaml files with their directory structure plus the file name
# without the yaml extension, which will be used to set the namespaces.
# Ex: file xyz/openbmc_project/Error/Callout/Device.errors.yaml
# will have namespce xyz/openbmc_project/Error/Callout/Device
def get_error_yaml_files(i_yaml_dir, i_test_dir):
    yaml_files = dict()
    if i_yaml_dir != "None":
        for root, dirs, files in os.walk(i_yaml_dir):
            for files in \
                    [file for file in files if file.endswith('.errors.yaml')]:
                splitdir = root.split(i_yaml_dir)[1] + "/" + files[:-12]
                if splitdir.startswith("/"):
                    splitdir = splitdir[1:]
                yaml_files[(os.path.join(root, files))] = splitdir
    for root, dirs, files in os.walk(i_test_dir):
        for files in [file for file in files if file.endswith('.errors.yaml')]:
            splitdir = root.split(i_test_dir)[1] + "/" + files[:-12]
            yaml_files[(os.path.join(root, files))] = splitdir
    return yaml_files


def get_meta_yaml_file(i_error_yaml_file):
    # the meta data will be defined in file name where we replace
    # <Interface>.errors.yaml with <Interface>.metadata.yaml
    meta_yaml = i_error_yaml_file.replace("errors", "metadata")
    return meta_yaml


def get_cpp_type(i_type):
    typeMap = {
        'boolean': 'bool',
        'int8': 'int8_t',
        'int16': 'int16_t',
        'int32': 'int32_t',
        'int64': 'int64_t',
        'uint8': 'uint8_t',
        'uint16': 'uint16_t',
        'uint32': 'uint32_t',
        'uint64': 'uint64_t',
        'double': 'double',
        # const char* aids usage of constexpr
        'string': 'const char*'}

    return typeMap[i_type]


def gen_elog_hpp(i_yaml_dir, i_test_dir, i_output_hpp,
                 i_template_dir, i_elog_mako):
    r"""
    Read  yaml file(s) under input yaml dir, grab the relevant data and call
    the mako template to generate the output header file.

    Description of arguments:
    i_yaml_dir                  directory containing base error yaml files
    i_test_dir                  directory containing test error yaml files
    i_output_hpp                name of the to be generated output hpp
    i_template_dir              directory containing error mako templates
    i_elog_mako                 error mako template to render
    """

    # Input parameters to mako template
    errors = list()  # Main error codes
    error_msg = dict()  # Error msg that corresponds to error code
    error_lvl = dict()  # Error code log level (debug, info, error, ...)
    meta = dict()  # The meta data names associated (ERRNO, FILE_NAME, ...)
    meta_data = dict()  # The meta data info (type, format)
    parents = dict()
    metadata_process = dict()  # metadata that have the 'process' keyword set

    # Verify the input mako file
    template_path = os.path.join(i_template_dir, i_elog_mako)
    if (not (os.path.isfile(template_path))):
        print("Cannot find input template file " + template_path)
        exit(1)
    template_path = os.path.abspath(template_path)

    error_yamls = get_error_yaml_files(i_yaml_dir, i_test_dir)

    for error_yaml in error_yamls:
        # Verify the error yaml file
        if (not (os.path.isfile(error_yaml))):
            print("Cannot find input yaml file " + error_yaml)
            exit(1)

        # Verify the metadata yaml file
        meta_yaml = get_meta_yaml_file(error_yaml)

        get_elog_data(error_yaml,
                      meta_yaml,
                      error_yamls[error_yaml],
                      # Last arg is a tuple
                      (errors,
                       error_msg,
                       error_lvl,
                       meta,
                       meta_data,
                       parents,
                       metadata_process))

    if(not check_error_inheritance(errors, parents)):
        print("Error - failed to validate error inheritance")
        exit(1)

    errors = order_inherited_errors(errors, parents)

    # Load the mako template and call it with the required data
    yaml_dir = i_yaml_dir.strip("./")
    yaml_dir = yaml_dir.strip("../")
    template = Template(filename=template_path)
    f = open(i_output_hpp, 'w')
    f.write(template.render(
            errors=errors,
            error_msg=error_msg,
            error_lvl=error_lvl,
            meta=meta,
            meta_data=meta_data,
            parents=parents,
            metadata_process=metadata_process))
    f.close()


def get_elog_data(i_elog_yaml,
                  i_elog_meta_yaml,
                  i_namespace,
                  o_elog_data):
    r"""
    Parse the error and metadata yaml files in order to pull out
    error metadata.

    Use default values if metadata yaml file is not found.

    Description of arguments:
    i_elog_yaml                 error yaml file
    i_elog_meta_yaml            metadata yaml file
    i_namespace                 namespace data
    o_elog_data                 error metadata
    """
    (errors, error_msg, error_lvl, meta,
     meta_data, parents, metadata_process) = o_elog_data
    ifile = yaml.safe_load(open(i_elog_yaml))

    # for all the errors in error yaml file
    for error in ifile:
        if 'name' not in error:
            print("Error - Did not find name in entry %s in file %s " % (
                str(error), i_elog_yaml))
            exit(1)
        fullname = i_namespace.replace('/', '.') + ('.') + error['name']
        errors.append(fullname)

        if 'description' in error:
            error_msg[fullname] = error['description'].strip()

        # set default values
        error_lvl[fullname] = "ERR"
        parents[fullname] = None

        # check if meta data yaml file is found
        if not os.path.isfile(i_elog_meta_yaml):
            continue
        mfile = yaml.safe_load(open(i_elog_meta_yaml))

        # Find the meta data entry
        match = None
        for meta_entry in mfile:
            if meta_entry['name'] == error['name']:
                match = meta_entry
                break

        if match is None:
            print("Error - Did not find error named %s in %s" % (
                error['name'], i_elog_meta_yaml))
            continue

        error_lvl[fullname] = match.get('level', 'ERR')

        # Get 0th inherited error (current support - single inheritance)
        if 'inherits' in match:
            parents[fullname] = match['inherits'][0]

        # Put all errors in meta[] even the meta is empty
        # so that child errors could inherits such error without meta
        tmp_meta = []
        if 'meta' in match:
            # grab all the meta data fields and info
            for i in match['meta']:
                str_short = i['str'].split('=')[0]
                tmp_meta.append(str_short)
                meta_data[str_short] = {}
                meta_data[str_short]['str'] = i['str']
                meta_data[str_short]['str_short'] = str_short
                meta_data[str_short]['type'] = get_cpp_type(i['type'])
                if ('process' in i) and (i['process'] is True):
                    metadata_process[str_short] = fullname + "." + str_short
        meta[fullname] = tmp_meta

    # Debug
    # for i in errors:
    #   print "ERROR: " + errors[i]
    #   print " MSG:  " + error_msg[errors[i]]
    #   print " LVL:  " + error_lvl[errors[i]]
    #   print " META: "
    #   print meta[i]


def main(i_args):
    parser = OptionParser()

    parser.add_option("-m", "--mako", dest="elog_mako",
                      default="elog-gen-template.mako.hpp",
                      help="input mako template file to use")

    parser.add_option("-o", "--output", dest="output_hpp",
                      default="elog-errors.hpp",
                      help="output hpp to generate, elog-errors.hpp default")

    parser.add_option("-y", "--yamldir", dest="yamldir",
                      default="None",
                      help="Base directory of yaml files to process")

    parser.add_option("-u", "--testdir", dest="testdir",
                      default="./tools/example/",
                      help="Unit test directory of yaml files to process")

    parser.add_option("-t", "--templatedir", dest="templatedir",
                      default="phosphor-logging/templates/",
                      help="Base directory of files to process")

    (options, args) = parser.parse_args(i_args)

    gen_elog_hpp(options.yamldir,
                 options.testdir,
                 options.output_hpp,
                 options.templatedir,
                 options.elog_mako)


# Only run if it's a script
if __name__ == '__main__':
    main(sys.argv[1:])
