#!/usr/bin/env python

'''Phosphor DBus Monitor YAML parser and code generator.

The parser workflow is broken down as follows:
  1 - Import YAML files as native python type(s) instance(s).
  2 - Create an instance of the Everything class from the
        native python type instance(s) with the Everything.load
        method.
  3 - The Everything class constructor orchestrates conversion of the
        native python type(s) instances(s) to render helper types.
        Each render helper type constructor imports its attributes
        from the native python type(s) instances(s).
  4 - Present the converted YAML to the command processing method
        requested by the script user.
'''

import os
import sys
import yaml
import mako.lookup
from argparse import ArgumentParser
from sdbusplus.renderer import Renderer
from sdbusplus.namedelement import NamedElement
import sdbusplus.property


class InvalidConfigError(BaseException):
    '''General purpose config file parsing error.'''

    def __init__(self, path, msg):
        '''Display configuration file with the syntax
        error and the error message.'''

        self.config = path
        self.msg = msg


class NotUniqueError(InvalidConfigError):
    '''Within a config file names must be unique.
    Display the config file with the duplicate and
    the duplicate itself.'''

    def __init__(self, path, cls, *names):
        fmt = 'Duplicate {0}: "{1}"'
        super(NotUniqueError, self).__init__(
            path, fmt.format(cls, ' '.join(names)))


def get_index(objs, cls, name, config=None):
    '''Items are usually rendered as C++ arrays and as
    such are stored in python lists.  Given an item name
    its class, and an optional config file filter, find
    the item index.'''

    for i, x in enumerate(objs.get(cls, [])):
        if config and x.configfile != config:
            continue
        if x.name != name:
            continue

        return i
    raise InvalidConfigError(config, 'Could not find name: "{0}"'.format(name))


def exists(objs, cls, name, config=None):
    '''Check to see if an item already exists in a list given
    the item name.'''

    try:
        get_index(objs, cls, name, config)
    except:
        return False

    return True


def add_unique(obj, *a, **kw):
    '''Add an item to one or more lists unless already present,
    with an option to constrain the search to a specific config file.'''

    for container in a:
        if not exists(container, obj.cls, obj.name, config=kw.get('config')):
            container.setdefault(obj.cls, []).append(obj)


class Cast(object):
    '''Decorate an argument by casting it.'''

    def __init__(self, cast, target):
        '''cast is the cast type (static, const, etc...).
           target is the cast target type.'''
        self.cast = cast
        self.target = target

    def __call__(self, arg):
        return '{0}_cast<{1}>({2})'.format(self.cast, self.target, arg)


class Literal(object):
    '''Decorate an argument with a literal operator.'''

    integer_types = [
        'int16',
        'int32',
        'int64',
        'uint16',
        'uint32',
        'uint64'
    ]

    def __init__(self, type):
        self.type = type

    def __call__(self, arg):
        if 'uint' in self.type:
            arg = '{0}ull'.format(arg)
        elif 'int' in self.type:
            arg = '{0}ll'.format(arg)

        if self.type in self.integer_types:
            return Cast('static', '{0}_t'.format(self.type))(arg)
        elif self.type == 'byte':
            return Cast('static', 'uint8_t'.format(self.type))(arg)

        if self.type == 'string':
            return '{0}s'.format(arg)

        return arg


class FixBool(object):
    '''Un-capitalize booleans.'''

    def __call__(self, arg):
        return '{0}'.format(arg.lower())


class Quote(object):
    '''Decorate an argument by quoting it.'''

    def __call__(self, arg):
        return '"{0}"'.format(arg)


class Argument(NamedElement, Renderer):
    '''Define argument type inteface.'''

    def __init__(self, **kw):
        self.type = kw.pop('type', None)
        super(Argument, self).__init__(**kw)

    def argument(self, loader, indent):
        raise NotImplementedError


class TrivialArgument(Argument):
    '''Non-array type arguments.'''

    def __init__(self, **kw):
        self.value = kw.pop('value')
        self.decorators = kw.pop('decorators', [])
        if kw.get('type', None):
            self.decorators.insert(0, Literal(kw['type']))
        if kw.get('type', None) == 'string':
            self.decorators.insert(0, Quote())
        if kw.get('type', None) == 'boolean':
            self.decorators.insert(0, FixBool())

        super(TrivialArgument, self).__init__(**kw)

    def argument(self, loader, indent):
        a = str(self.value)
        for d in self.decorators:
            a = d(a)

        return a


class Metadata(Argument):
    '''Metadata type arguments.'''

    def __init__(self, **kw):
        self.value = kw.pop('value')
        self.decorators = kw.pop('decorators', [])
        if kw.get('type', None) == 'string':
            self.decorators.insert(0, Quote())

        super(Metadata, self).__init__(**kw)

    def argument(self, loader, indent):
        a = str(self.value)
        for d in self.decorators:
            a = d(a)

        return a


class Indent(object):
    '''Help templates be depth agnostic.'''

    def __init__(self, depth=0):
        self.depth = depth

    def __add__(self, depth):
        return Indent(self.depth + depth)

    def __call__(self, depth):
        '''Render an indent at the current depth plus depth.'''
        return 4*' '*(depth + self.depth)


class ConfigEntry(NamedElement):
    '''Base interface for rendered items.'''

    def __init__(self, *a, **kw):
        '''Pop the configfile/class/subclass keywords.'''

        self.configfile = kw.pop('configfile')
        self.cls = kw.pop('class')
        self.subclass = kw.pop(self.cls)
        super(ConfigEntry, self).__init__(**kw)

    def factory(self, objs):
        ''' Optional factory interface for subclasses to add
        additional items to be rendered.'''

        pass

    def setup(self, objs):
        ''' Optional setup interface for subclasses, invoked
        after all factory methods have been run.'''

        pass


class Path(ConfigEntry):
    '''Path/metadata association.'''

    def __init__(self, *a, **kw):
        super(Path, self).__init__(**kw)

        if self.name['meta'].upper() != self.name['meta']:
            raise InvalidConfigError(
                self.configfile,
                'Metadata tag "{0}" must be upper case.'.format(
                    self.name['meta']))

    def factory(self, objs):
        '''Create path and metadata elements.'''

        args = {
            'class': 'pathname',
            'pathname': 'element',
            'name': self.name['path']
        }
        add_unique(ConfigEntry(
            configfile=self.configfile, **args), objs)

        args = {
            'class': 'meta',
            'meta': 'element',
            'name': self.name['meta']
        }
        add_unique(ConfigEntry(
            configfile=self.configfile, **args), objs)

        super(Path, self).factory(objs)

    def setup(self, objs):
        '''Resolve path and metadata names to indices.'''

        self.path = get_index(
            objs, 'pathname', self.name['path'])
        self.meta = get_index(
            objs, 'meta', self.name['meta'])

        super(Path, self).setup(objs)


class Property(ConfigEntry):
    '''Property/interface/metadata association.'''

    def __init__(self, *a, **kw):
        super(Property, self).__init__(**kw)

        if self.name['meta'].upper() != self.name['meta']:
            raise InvalidConfigError(
                self.configfile,
                'Metadata tag "{0}" must be upper case.'.format(
                    self.name['meta']))

    def factory(self, objs):
        '''Create interface, property name and metadata elements.'''

        args = {
            'class': 'interface',
            'interface': 'element',
            'name': self.name['interface']
        }
        add_unique(ConfigEntry(
            configfile=self.configfile, **args), objs)

        args = {
            'class': 'propertyname',
            'propertyname': 'element',
            'name': self.name['property']
        }
        add_unique(ConfigEntry(
            configfile=self.configfile, **args), objs)

        args = {
            'class': 'meta',
            'meta': 'element',
            'name': self.name['meta']
        }
        add_unique(ConfigEntry(
            configfile=self.configfile, **args), objs)

        super(Property, self).factory(objs)

    def setup(self, objs):
        '''Resolve interface, property and metadata to indices.'''

        self.interface = get_index(
            objs, 'interface', self.name['interface'])
        self.prop = get_index(
            objs, 'propertyname', self.name['property'])
        self.meta = get_index(
            objs, 'meta', self.name['meta'])

        super(Property, self).setup(objs)


class Instance(ConfigEntry):
    '''Property/Path association.'''

    def __init__(self, *a, **kw):
        super(Instance, self).__init__(**kw)

    def setup(self, objs):
        '''Resolve elements to indices.'''

        self.interface = get_index(
            objs, 'interface', self.name['property']['interface'])
        self.prop = get_index(
            objs, 'propertyname', self.name['property']['property'])
        self.propmeta = get_index(
            objs, 'meta', self.name['property']['meta'])
        self.path = get_index(
            objs, 'pathname', self.name['path']['path'])
        self.pathmeta = get_index(
            objs, 'meta', self.name['path']['meta'])

        super(Instance, self).setup(objs)


class Group(ConfigEntry):
    '''Pop the members keyword for groups.'''

    def __init__(self, *a, **kw):
        self.members = kw.pop('members')
        super(Group, self).__init__(**kw)


class ImplicitGroup(Group):
    '''Provide a factory method for groups whose members are
    not explicitly declared in the config files.'''

    def __init__(self, *a, **kw):
        super(ImplicitGroup, self).__init__(**kw)

    def factory(self, objs):
        '''Create group members.'''

        factory = Everything.classmap(self.subclass, 'element')
        for m in self.members:
            args = {
                'class': self.subclass,
                self.subclass: 'element',
                'name': m
            }

            obj = factory(configfile=self.configfile, **args)
            add_unique(obj, objs)
            obj.factory(objs)

        super(ImplicitGroup, self).factory(objs)


class GroupOfPaths(ImplicitGroup):
    '''Path group config file directive.'''

    def __init__(self, *a, **kw):
        super(GroupOfPaths, self).__init__(**kw)

    def setup(self, objs):
        '''Resolve group members.'''

        def map_member(x):
            path = get_index(
                objs, 'pathname', x['path'])
            meta = get_index(
                objs, 'meta', x['meta'])
            return (path, meta)

        self.members = map(
            map_member,
            self.members)

        super(GroupOfPaths, self).setup(objs)


class GroupOfProperties(ImplicitGroup):
    '''Property group config file directive.'''

    def __init__(self, *a, **kw):
        self.type = kw.pop('type')
        self.datatype = sdbusplus.property.Property(
            name=kw.get('name'),
            type=self.type).cppTypeName

        super(GroupOfProperties, self).__init__(**kw)

    def setup(self, objs):
        '''Resolve group members.'''

        def map_member(x):
            iface = get_index(
                objs, 'interface', x['interface'])
            prop = get_index(
                objs, 'propertyname', x['property'])
            meta = get_index(
                objs, 'meta', x['meta'])

            return (iface, prop, meta)

        self.members = map(
            map_member,
            self.members)

        super(GroupOfProperties, self).setup(objs)


class GroupOfInstances(ImplicitGroup):
    '''A group of property instances.'''

    def __init__(self, *a, **kw):
        super(GroupOfInstances, self).__init__(**kw)

    def setup(self, objs):
        '''Resolve group members.'''

        def map_member(x):
            path = get_index(objs, 'pathname', x['path']['path'])
            pathmeta = get_index(objs, 'meta', x['path']['meta'])
            interface = get_index(
                objs, 'interface', x['property']['interface'])
            prop = get_index(objs, 'propertyname', x['property']['property'])
            propmeta = get_index(objs, 'meta', x['property']['meta'])
            instance = get_index(objs, 'instance', x)

            return (path, pathmeta, interface, prop, propmeta, instance)

        self.members = map(
            map_member,
            self.members)

        super(GroupOfInstances, self).setup(objs)


class HasPropertyIndex(ConfigEntry):
    '''Handle config file directives that require an index to be
    constructed.'''

    def __init__(self, *a, **kw):
        self.paths = kw.pop('paths')
        self.properties = kw.pop('properties')
        super(HasPropertyIndex, self).__init__(**kw)

    def factory(self, objs):
        '''Create a group of instances for this index.'''

        members = []
        path_group = get_index(
            objs, 'pathgroup', self.paths, config=self.configfile)
        property_group = get_index(
            objs, 'propertygroup', self.properties, config=self.configfile)

        for path in objs['pathgroup'][path_group].members:
            for prop in objs['propertygroup'][property_group].members:
                member = {
                    'path': path,
                    'property': prop,
                }
                members.append(member)

        args = {
            'members': members,
            'class': 'instancegroup',
            'instancegroup': 'instance',
            'name': '{0} {1}'.format(self.paths, self.properties)
        }

        group = GroupOfInstances(configfile=self.configfile, **args)
        add_unique(group, objs, config=self.configfile)
        group.factory(objs)

        super(HasPropertyIndex, self).factory(objs)

    def setup(self, objs):
        '''Resolve path, property, and instance groups.'''

        self.instances = get_index(
            objs,
            'instancegroup',
            '{0} {1}'.format(self.paths, self.properties),
            config=self.configfile)
        self.paths = get_index(
            objs,
            'pathgroup',
            self.paths,
            config=self.configfile)
        self.properties = get_index(
            objs,
            'propertygroup',
            self.properties,
            config=self.configfile)
        self.datatype = objs['propertygroup'][self.properties].datatype
        self.type = objs['propertygroup'][self.properties].type

        super(HasPropertyIndex, self).setup(objs)


class PropertyWatch(HasPropertyIndex):
    '''Handle the property watch config file directive.'''

    def __init__(self, *a, **kw):
        self.callback = kw.pop('callback', None)
        super(PropertyWatch, self).__init__(**kw)

    def setup(self, objs):
        '''Resolve optional callback.'''

        if self.callback:
            self.callback = get_index(
                objs,
                'callback',
                self.callback,
                config=self.configfile)

        super(PropertyWatch, self).setup(objs)


class Callback(HasPropertyIndex):
    '''Interface and common logic for callbacks.'''

    def __init__(self, *a, **kw):
        super(Callback, self).__init__(**kw)


class ConditionCallback(ConfigEntry, Renderer):
    '''Handle the journal callback config file directive.'''

    def __init__(self, *a, **kw):
        self.condition = kw.pop('condition')
        self.instance = kw.pop('instance')
        self.defer = kw.pop('defer', None)
        super(ConditionCallback, self).__init__(**kw)

    def factory(self, objs):
        '''Create a graph instance for this callback.'''

        args = {
            'configfile': self.configfile,
            'members': [self.instance],
            'class': 'callbackgroup',
            'callbackgroup': 'callback',
            'name': [self.instance]
        }

        entry = CallbackGraphEntry(**args)
        add_unique(entry, objs, config=self.configfile)

        super(ConditionCallback, self).factory(objs)

    def setup(self, objs):
        '''Resolve condition and graph entry.'''

        self.graph = get_index(
            objs,
            'callbackgroup',
            [self.instance],
            config=self.configfile)

        self.condition = get_index(
            objs,
            'condition',
            self.name,
            config=self.configfile)

        super(ConditionCallback, self).setup(objs)

    def construct(self, loader, indent):
        return self.render(
            loader,
            'conditional.mako.cpp',
            c=self,
            indent=indent)


class Condition(HasPropertyIndex):
    '''Interface and common logic for conditions.'''

    def __init__(self, *a, **kw):
        self.callback = kw.pop('callback')
        self.defer = kw.pop('defer', None)
        super(Condition, self).__init__(**kw)

    def factory(self, objs):
        '''Create a callback instance for this conditional.'''

        args = {
            'configfile': self.configfile,
            'condition': self.name,
            'class': 'callback',
            'callback': 'conditional',
            'instance': self.callback,
            'name': self.name,
            'defer': self.defer
        }

        callback = ConditionCallback(**args)
        add_unique(callback, objs, config=self.configfile)
        callback.factory(objs)

        super(Condition, self).factory(objs)


class CountCondition(Condition, Renderer):
    '''Handle the count condition config file directive.'''

    def __init__(self, *a, **kw):
        self.countop = kw.pop('countop')
        self.countbound = kw.pop('countbound')
        self.op = kw.pop('op')
        self.bound = kw.pop('bound')
        self.oneshot = TrivialArgument(
            type='boolean',
            value=kw.pop('oneshot', False))
        super(CountCondition, self).__init__(**kw)

    def setup(self, objs):
        '''Resolve type.'''

        super(CountCondition, self).setup(objs)
        self.bound = TrivialArgument(
            type=self.type,
            value=self.bound)

    def construct(self, loader, indent):
        return self.render(
            loader,
            'count.mako.cpp',
            c=self,
            indent=indent)


class Journal(Callback, Renderer):
    '''Handle the journal callback config file directive.'''

    def __init__(self, *a, **kw):
        self.severity = kw.pop('severity')
        self.message = kw.pop('message')
        super(Journal, self).__init__(**kw)

    def construct(self, loader, indent):
        return self.render(
            loader,
            'journal.mako.cpp',
            c=self,
            indent=indent)


class Elog(Callback, Renderer):
    '''Handle the elog callback config file directive.'''

    def __init__(self, *a, **kw):
        self.error = kw.pop('error')
        self.metadata = [Metadata(**x) for x in kw.pop('metadata', {})]
        super(Elog, self).__init__(**kw)

    def construct(self, loader, indent):
        with open('errors.hpp', 'a') as fd:
            fd.write(
                self.render(
                    loader,
                    'errors.mako.hpp',
                    c=self))
        return self.render(
            loader,
            'elog.mako.cpp',
            c=self,
            indent=indent)

class Event(Callback, Renderer):
    '''Handle the event callback config file directive.'''

    def __init__(self, *a, **kw):
        self.eventName = kw.pop('eventName')
        self.eventMessage = kw.pop('eventMessage')
        super(Event, self).__init__(**kw)

    def construct(self, loader, indent):
        return self.render(
            loader,
            'event.mako.cpp',
            c=self,
            indent=indent)

class ResolveCallout(Callback, Renderer):
    '''Handle the 'resolve callout' callback config file directive.'''

    def __init__(self, *a, **kw):
        self.callout = kw.pop('callout')
        super(ResolveCallout, self).__init__(**kw)

    def construct(self, loader, indent):
        return self.render(
            loader,
            'resolve_errors.mako.cpp',
            c=self,
            indent=indent)


class Method(ConfigEntry, Renderer):
    '''Handle the method callback config file directive.'''

    def __init__(self, *a, **kw):
        self.service = kw.pop('service')
        self.path = kw.pop('path')
        self.interface = kw.pop('interface')
        self.method = kw.pop('method')
        self.args = [TrivialArgument(**x) for x in kw.pop('args', {})]
        super(Method, self).__init__(**kw)

    def factory(self, objs):
        args = {
            'class': 'interface',
            'interface': 'element',
            'name': self.service
        }
        add_unique(ConfigEntry(
            configfile=self.configfile, **args), objs)

        args = {
            'class': 'pathname',
            'pathname': 'element',
            'name': self.path
        }
        add_unique(ConfigEntry(
            configfile=self.configfile, **args), objs)

        args = {
            'class': 'interface',
            'interface': 'element',
            'name': self.interface
        }
        add_unique(ConfigEntry(
            configfile=self.configfile, **args), objs)

        args = {
            'class': 'propertyname',
            'propertyname': 'element',
            'name': self.method
        }
        add_unique(ConfigEntry(
            configfile=self.configfile, **args), objs)

        super(Method, self).factory(objs)

    def setup(self, objs):
        '''Resolve elements.'''

        self.service = get_index(
            objs,
            'interface',
            self.service)

        self.path = get_index(
            objs,
            'pathname',
            self.path)

        self.interface = get_index(
            objs,
            'interface',
            self.interface)

        self.method = get_index(
            objs,
            'propertyname',
            self.method)

        super(Method, self).setup(objs)

    def construct(self, loader, indent):
        return self.render(
            loader,
            'method.mako.cpp',
            c=self,
            indent=indent)


class CallbackGraphEntry(Group):
    '''An entry in a traversal list for groups of callbacks.'''

    def __init__(self, *a, **kw):
        super(CallbackGraphEntry, self).__init__(**kw)

    def setup(self, objs):
        '''Resolve group members.'''

        def map_member(x):
            return get_index(
                objs, 'callback', x, config=self.configfile)

        self.members = map(
            map_member,
            self.members)

        super(CallbackGraphEntry, self).setup(objs)


class GroupOfCallbacks(ConfigEntry, Renderer):
    '''Handle the callback group config file directive.'''

    def __init__(self, *a, **kw):
        self.members = kw.pop('members')
        super(GroupOfCallbacks, self).__init__(**kw)

    def factory(self, objs):
        '''Create a graph instance for this group of callbacks.'''

        args = {
            'configfile': self.configfile,
            'members': self.members,
            'class': 'callbackgroup',
            'callbackgroup': 'callback',
            'name': self.members
        }

        entry = CallbackGraphEntry(**args)
        add_unique(entry, objs, config=self.configfile)

        super(GroupOfCallbacks, self).factory(objs)

    def setup(self, objs):
        '''Resolve graph entry.'''

        self.graph = get_index(
            objs, 'callbackgroup', self.members, config=self.configfile)

        super(GroupOfCallbacks, self).setup(objs)

    def construct(self, loader, indent):
        return self.render(
            loader,
            'callbackgroup.mako.cpp',
            c=self,
            indent=indent)


class Everything(Renderer):
    '''Parse/render entry point.'''

    @staticmethod
    def classmap(cls, sub=None):
        '''Map render item class and subclass entries to the appropriate
        handler methods.'''

        class_map = {
            'path': {
                'element': Path,
            },
            'pathgroup': {
                'path': GroupOfPaths,
            },
            'propertygroup': {
                'property': GroupOfProperties,
            },
            'property': {
                'element': Property,
            },
            'watch': {
                'property': PropertyWatch,
            },
            'instance': {
                'element': Instance,
            },
            'callback': {
                'journal': Journal,
                'elog': Elog,
                'event': Event,
                'group': GroupOfCallbacks,
                'method': Method,
                'resolve callout': ResolveCallout,
            },
            'condition': {
                'count': CountCondition,
            },
        }

        if cls not in class_map:
            raise NotImplementedError('Unknown class: "{0}"'.format(cls))
        if sub not in class_map[cls]:
            raise NotImplementedError('Unknown {0} type: "{1}"'.format(
                cls, sub))

        return class_map[cls][sub]

    @staticmethod
    def load_one_yaml(path, fd, objs):
        '''Parse a single YAML file.  Parsing occurs in three phases.
        In the first phase a factory method associated with each
        configuration file directive is invoked.  These factory
        methods generate more factory methods.  In the second
        phase the factory methods created in the first phase
        are invoked.  In the last phase a callback is invoked on
        each object created in phase two.  Typically the callback
        resolves references to other configuration file directives.'''

        factory_objs = {}
        for x in yaml.safe_load(fd.read()) or {}:

            # Create factory object for this config file directive.
            cls = x['class']
            sub = x.get(cls)
            if cls == 'group':
                cls = '{0}group'.format(sub)

            factory = Everything.classmap(cls, sub)
            obj = factory(configfile=path, **x)

            # For a given class of directive, validate the file
            # doesn't have any duplicate names (duplicates are
            # ok across config files).
            if exists(factory_objs, obj.cls, obj.name, config=path):
                raise NotUniqueError(path, cls, obj.name)

            factory_objs.setdefault(cls, []).append(obj)
            objs.setdefault(cls, []).append(obj)

        for cls, items in factory_objs.items():
            for obj in items:
                # Add objects for template consumption.
                obj.factory(objs)

    @staticmethod
    def load(args):
        '''Aggregate all the YAML in the input directory
        into a single aggregate.'''

        objs = {}
        yaml_files = filter(
            lambda x: x.endswith('.yaml'),
            os.listdir(args.inputdir))

        yaml_files.sort()

        for x in yaml_files:
            path = os.path.join(args.inputdir, x)
            with open(path, 'r') as fd:
                Everything.load_one_yaml(path, fd, objs)

        # Configuration file directives reference each other via
        # the name attribute; however, when rendered the reference
        # is just an array index.
        #
        # At this point all objects have been created but references
        # have not been resolved to array indices.  Instruct objects
        # to do that now.
        for cls, items in objs.items():
            for obj in items:
                obj.setup(objs)

        return Everything(**objs)

    def __init__(self, *a, **kw):
        self.pathmeta = kw.pop('path', [])
        self.paths = kw.pop('pathname', [])
        self.meta = kw.pop('meta', [])
        self.pathgroups = kw.pop('pathgroup', [])
        self.interfaces = kw.pop('interface', [])
        self.properties = kw.pop('property', [])
        self.propertynames = kw.pop('propertyname', [])
        self.propertygroups = kw.pop('propertygroup', [])
        self.instances = kw.pop('instance', [])
        self.instancegroups = kw.pop('instancegroup', [])
        self.watches = kw.pop('watch', [])
        self.callbacks = kw.pop('callback', [])
        self.callbackgroups = kw.pop('callbackgroup', [])
        self.conditions = kw.pop('condition', [])

        super(Everything, self).__init__(**kw)

    def generate_cpp(self, loader):
        '''Render the template with the provided data.'''
        # errors.hpp is used by generated.hpp to included any error.hpp files
        open('errors.hpp', 'w+')

        with open(args.output, 'w') as fd:
            fd.write(
                self.render(
                    loader,
                    args.template,
                    meta=self.meta,
                    properties=self.properties,
                    propertynames=self.propertynames,
                    interfaces=self.interfaces,
                    paths=self.paths,
                    pathmeta=self.pathmeta,
                    pathgroups=self.pathgroups,
                    propertygroups=self.propertygroups,
                    instances=self.instances,
                    watches=self.watches,
                    instancegroups=self.instancegroups,
                    callbacks=self.callbacks,
                    callbackgroups=self.callbackgroups,
                    conditions=self.conditions,
                    indent=Indent()))

if __name__ == '__main__':
    script_dir = os.path.dirname(os.path.realpath(__file__))
    valid_commands = {
        'generate-cpp': 'generate_cpp',
    }

    parser = ArgumentParser(
        description='Phosphor DBus Monitor (PDM) YAML '
        'scanner and code generator.')

    parser.add_argument(
        "-o", "--out", dest="output",
        default='generated.cpp',
        help="Generated output file name and path.")
    parser.add_argument(
        '-t', '--template', dest='template',
        default='generated.mako.hpp',
        help='The top level template to render.')
    parser.add_argument(
        '-p', '--template-path', dest='template_search',
        default=script_dir,
        help='The space delimited mako template search path.')
    parser.add_argument(
        '-d', '--dir', dest='inputdir',
        default=os.path.join(script_dir, 'example'),
        help='Location of files to process.')
    parser.add_argument(
        'command', metavar='COMMAND', type=str,
        choices=valid_commands.keys(),
        help='%s.' % " | ".join(valid_commands.keys()))

    args = parser.parse_args()

    if sys.version_info < (3, 0):
        lookup = mako.lookup.TemplateLookup(
            directories=args.template_search.split(),
            disable_unicode=True)
    else:
        lookup = mako.lookup.TemplateLookup(
            directories=args.template_search.split())
    try:
        function = getattr(
            Everything.load(args),
            valid_commands[args.command])
        function(lookup)
    except InvalidConfigError as e:
        sys.stdout.write('{0}: {1}\n\n'.format(e.config, e.msg))
        raise
