#!/usr/bin/env python3

'''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)
        elif self.type == 'double':
            return Cast('static', 'double'.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 interface.'''

    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 OpArgument(Argument):
    '''Operation type arguments.'''

    def __init__(self, **kw):
        self.op = kw.pop('op')
        self.bound = kw.pop('bound')
        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(OpArgument, self).__init__(**kw)

    def argument(self, loader, indent):
        a = str(self.bound)
        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)

        # TODO: NamedElement requires 'name' to be a string, but in many cases
        #       this script treats 'name' as a dict.  Save the property off and
        #       insert it after ConfigEntry does its own thing to avoid
        #       exceptions.  This should be refactored throughout the whole
        #       script to not overload 'name' as a dict.
        name_save = kw.pop('name')
        super(ConfigEntry, self).__init__(**kw)
        self.name = name_save

    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 PathInstance(ConfigEntry):
    '''Path association.'''

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

    def setup(self, objs):
        '''Resolve elements to indices.'''
        self.path = self.name['path']['path']
        self.pathmeta = self.name['path']['meta']
        super(PathInstance, 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 GroupOfPathInstances(ImplicitGroup):
    '''A group of path instances.'''

    def __init__(self, *a, **kw):
        super(GroupOfPathInstances, 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'])
            pathinstance = get_index(objs, 'pathinstance', x)
            return (path, pathmeta, pathinstance)

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

        super(GroupOfPathInstances, 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 HasPathIndex(ConfigEntry):
    '''Handle config file directives that require an index to be
    constructed.'''

    def __init__(self, *a, **kw):
        self.paths = kw.pop('paths')
        super(HasPathIndex, 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)

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

        args = {
            'members': members,
            'class': 'pathinstancegroup',
            'pathinstancegroup': 'pathinstance',
            'name': '{0}'.format(self.paths)
        }

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

        super(HasPathIndex, self).factory(objs)

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

        self.pathinstances = get_index(
            objs,
            'pathinstancegroup',
            '{0}'.format(self.paths),
            config=self.configfile)
        self.paths = get_index(
            objs,
            'pathgroup',
            self.paths,
            config=self.configfile)
        super(HasPathIndex, self).setup(objs)

class GroupOfFilters(ConfigEntry):
    '''Handle config file directives that require an index for filters.'''

    def __init__(self, *a, **kw):
        # Pop filters data for adding to the available filters array
        self.type = kw.pop('type')
        self.datatype = kw.pop('datatype', None)
        self.filters = kw.pop('filters', None)

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

    def factory(self, objs):
        '''Modify filters to add the property value type and
        make them of operation argument type.'''
        if self.filters:
            # 'type' used within OpArgument to generate filter
            # argument values so add to each filter
            for f in self.filters:
                f['type'] = self.type
            self.filters = [OpArgument(**x) for x in self.filters]

        super(GroupOfFilters, self).factory(objs)

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

    def __init__(self, *a, **kw):
        # Pop optional filters for the properties being watched
        self.filters = kw.pop('filters', None)
        self.callback = kw.pop('callback', None)
        super(PropertyWatch, self).__init__(**kw)

    def factory(self, objs):
        '''Create any filters for this property watch.'''

        if self.filters:
            # Get the datatype(i.e. "int64_t") of the properties in this watch
            # (Made available after all `super` classes init'd)
            datatype = objs['propertygroup'][get_index(
                objs,
                'propertygroup',
                self.properties,
                config=self.configfile)].datatype
            # Get the type(i.e. "int64") of the properties in this watch
            # (Made available after all `super` classes init'd)
            type = objs['propertygroup'][get_index(
                objs,
                'propertygroup',
                self.properties,
                config=self.configfile)].type
            # Construct the data needed to make the filters for
            # this watch available.
            # *Note: 'class', 'subclass', 'name' are required for
            # storing the filter data(i.e. 'type', 'datatype', & 'filters')
            args = {
                'type': type,
                'datatype': datatype,
                'filters': self.filters,
                'class': 'filtersgroup',
                'filtersgroup': 'filters',
                'name': self.name,
            }
            # Init GroupOfFilters class with this watch's filters' arguments
            group = GroupOfFilters(configfile=self.configfile, **args)
            # Store this group of filters so it can be indexed later
            add_unique(group, objs, config=self.configfile)
            group.factory(objs)

        super(PropertyWatch, self).factory(objs)

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

        if self.filters:
            # Watch has filters, provide array index to access them
            self.filters = get_index(
                objs,
                'filtersgroup',
                self.name,
                config=self.configfile)

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

        super(PropertyWatch, self).setup(objs)

class PathWatch(HasPathIndex):
    '''Handle the path watch config file directive.'''

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

    def setup(self, objs):
        '''Resolve optional callback.'''
        if self.pathcallback:
            self.pathcallback = get_index(
                objs,
                'pathcallback',
                self.pathcallback,
                config=self.configfile)
        super(PathWatch, self).setup(objs)

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

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

class PathCallback(HasPathIndex):
    '''Interface and common logic for callbacks.'''

    def __init__(self, *a, **kw):
        super(PathCallback, 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 MedianCondition(Condition, Renderer):
    '''Handle the median condition config file directive.'''

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

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

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

    def construct(self, loader, indent):
        return self.render(
            loader,
            'median.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 EventPath(PathCallback, Renderer):
    '''Handle the event path callback config file directive.'''

    def __init__(self, *a, **kw):
        self.eventType = kw.pop('eventType')
        super(EventPath, self).__init__(**kw)

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

class ElogWithMetadata(Callback, Renderer):
    '''Handle the elog_with_metadata callback config file directive.'''

    def __init__(self, *a, **kw):
        self.error = kw.pop('error')
        self.metadata = kw.pop('metadata')
        super(ElogWithMetadata, 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_with_metadata.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 PathCallbackGraphEntry(Group):
    '''An entry in a traversal list for groups of callbacks.'''

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

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

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

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

        super(PathCallbackGraphEntry, 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 GroupOfPathCallbacks(ConfigEntry, Renderer):
    '''Handle the callback group config file directive.'''

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

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

        args = {
            'configfile': self.configfile,
            'members': self.members,
            'class': 'pathcallbackgroup',
            'pathcallbackgroup': 'pathcallback',
            'name': self.members
        }

        entry = PathCallbackGraphEntry(**args)
        add_unique(entry, objs, config=self.configfile)
        super(GroupOfPathCallbacks, self).factory(objs)

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

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

        super(GroupOfPathCallbacks, self).setup(objs)

    def construct(self, loader, indent):
        return self.render(
            loader,
            'callbackpathgroup.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,
            },
            'pathwatch': {
                'path': PathWatch,
            },
            'instance': {
                'element': Instance,
            },
            'pathinstance': {
                'element': PathInstance,
            },
            'callback': {
                'journal': Journal,
                'elog': Elog,
                'elog_with_metadata': ElogWithMetadata,
                'event': Event,
                'group': GroupOfCallbacks,
                'method': Method,
                'resolve callout': ResolveCallout,
            },
            'pathcallback': {
                'eventpath': EventPath,
                'grouppath': GroupOfPathCallbacks,
            },
            'condition': {
                'count': CountCondition,
                'median': MedianCondition,
            },
        }

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

        for x in sorted(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.pathinstances = kw.pop('pathinstance', [])
        self.instancegroups = kw.pop('instancegroup', [])
        self.pathinstancegroups = kw.pop('pathinstancegroup', [])
        self.watches = kw.pop('watch', [])
        self.pathwatches = kw.pop('pathwatch', [])
        self.callbacks = kw.pop('callback', [])
        self.pathcallbacks = kw.pop('pathcallback', [])
        self.callbackgroups = kw.pop('callbackgroup', [])
        self.pathcallbackgroups = kw.pop('pathcallbackgroup', [])
        self.conditions = kw.pop('condition', [])
        self.filters = kw.pop('filtersgroup', [])

        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,
                    pathinstances=self.pathinstances,
                    watches=self.watches,
                    pathwatches=self.pathwatches,
                    instancegroups=self.instancegroups,
                    pathinstancegroups=self.pathinstancegroups,
                    callbacks=self.callbacks,
                    pathcallbacks=self.pathcallbacks,
                    callbackgroups=self.callbackgroups,
                    pathcallbackgroups=self.pathcallbackgroups,
                    conditions=self.conditions,
                    filters=self.filters,
                    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
