#!/usr/bin/env python

r"""
This script will parse the input error log yaml file 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 gen_elog_hpp(i_rootdir, i_elog_yaml, i_elog_meta_yaml,
                 i_input_mako, i_output_hpp):
    r"""
    Read the input yaml file, grab the relevant data and call the mako
    template to generate the header file.

    Description of arguments:
    i_rootdir                    base directory to search for yaml files
    i_elog_yaml                  yaml file describing the error logs
    i_elog_meta_yaml             yaml file describing the meta data for elogs
    i_input_mako                 input mako template file to use
    i_output_hpp                 header file to output the generated code to
    """

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

    # see elog.yaml for reference
    ifile = yaml.safe_load(open("/".join((i_rootdir, i_elog_yaml))))
    mfile = yaml.safe_load(open(i_elog_meta_yaml))
    err_count = 0
    for i in ifile:
        match = None
        # Find the corresponding meta data for this entry
        for m in mfile:
            if m['name'] == i['name']:
                match = m
                break
        if (match is None):
            print "Error - Did not find meta data for " + i['name']
            exit(1)
        # Grab the main error and it's info
        errors[err_count] = i['name']
        error_msg[i['name']] = i['description']
        error_lvl[i['name']] = match['level']
        tmp_meta = []
        # grab all the meta data fields and info
        for j in match['meta']:
            str_short = j['str'].split('=')[0]
            tmp_meta.append(str_short)
            meta_data[str_short] = {}
            meta_data[str_short]['str'] = j['str']
            meta_data[str_short]['str_short'] = str_short
            meta_data[str_short]['type'] = j['type']
        meta.append(tmp_meta)
        err_count += 1

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

    # Load the mako template and call it with the required data
    mytemplate = Template(filename=i_input_mako)
    f = open(i_output_hpp, 'w')
    f.write(mytemplate.render(errors=errors, error_msg=error_msg,
                              error_lvl=error_lvl, meta=meta,
                              meta_data=meta_data,elog_yaml=i_elog_yaml))
    f.close()


def main(i_args):
    parser = OptionParser()

    parser.add_option("-e", "--elog", dest="elog_yaml",
                      default="xyz/openbmc_project/Example/Elog.errors.yaml",
                      help="input error yaml file to parse")

    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-gen.hpp",
                      help="output hpp to generate, elog-gen.hpp is default")

    parser.add_option("-r", "--rootdir", dest="rootdir",
                      default="example",
                      help="Base 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)

    # Verify the input yaml file
    yaml_path = "/".join((options.rootdir, options.elog_yaml))
    if (not (os.path.isfile(yaml_path))):
        print "Can not find input yaml file " + yaml_path
        exit(1)

    # the meta data will be defined in a similar file name where we replace
    # <Interface>.errors.yaml with <Interface>.logging.yaml
    meta_file = options.elog_yaml.replace("errors", "logging")
    meta_file = "/".join((options.rootdir, meta_file))
    if (not (os.path.isfile(meta_file))):
        print "Can not find meta yaml file " + meta_file
        exit(1)

    # Verify the input mako file
    template_path = "/".join((options.templatedir, options.elog_mako))
    if (not (os.path.isfile(template_path))):
        print "Can not find input template file " + template_path
        exit(1)

    gen_elog_hpp(options.rootdir,
                 options.elog_yaml,
                 meta_file,
                 template_path,
                 options.output_hpp)

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