#!/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.
"""

import os
import sys
from optparse import OptionParser

from mako.template import Template

import yaml


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:
            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:])
