#!/usr/bin/env python

'''Phosphor Inventory Manager 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 sys
import os
import argparse
import subprocess
import yaml
import mako.lookup
import sdbusplus.property
from sdbusplus.namedelement import NamedElement
from sdbusplus.renderer import Renderer


# Global busname for use within classes where necessary
busname = "xyz.openbmc_project.Inventory.Manager"


def cppTypeName(yaml_type):
    ''' Convert yaml types to cpp types.'''
    return sdbusplus.property.Property(type=yaml_type).cppTypeName


class InterfaceComposite(object):
    '''Compose interface properties.'''

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

    def interfaces(self):
        return self.dict.keys()

    def names(self, interface):
        names = []
        if self.dict[interface]:
            names = [NamedElement(name=x["name"]) for x in self.dict[interface]]
        return names


class Interface(list):
    '''Provide various interface transformations.'''

    def __init__(self, iface):
        super(Interface, self).__init__(iface.split('.'))

    def namespace(self):
        '''Represent as an sdbusplus namespace.'''
        return '::'.join(['sdbusplus'] + self[:-1] + ['server', self[-1]])

    def header(self):
        '''Represent as an sdbusplus server binding header.'''
        return os.sep.join(self + ['server.hpp'])

    def __str__(self):
        return '.'.join(self)


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 Template(NamedElement):
    '''Associate a template name with its namespace.'''

    def __init__(self, **kw):
        self.namespace = kw.pop('namespace', [])
        super(Template, self).__init__(**kw)

    def qualified(self):
        return '::'.join(self.namespace + [self.name])


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 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 = [
        'int8',
        'int16',
        'int32',
        'int64',
        'uint8',
        '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)

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

        return 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) == '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 InitializerList(Argument):
    '''Initializer list arguments.'''

    def __init__(self, **kw):
        self.values = kw.pop('values')
        super(InitializerList, self).__init__(**kw)

    def argument(self, loader, indent):
        return self.render(
            loader,
            'argument.mako.cpp',
            arg=self,
            indent=indent)


class DbusSignature(Argument):
    '''DBus signature arguments.'''

    def __init__(self, **kw):
        self.sig = {x: y for x, y in kw.iteritems()}
        kw.clear()
        super(DbusSignature, self).__init__(**kw)

    def argument(self, loader, indent):
        return self.render(
            loader,
            'signature.mako.cpp',
            signature=self,
            indent=indent)


class MethodCall(Argument):
    '''Render syntatically correct c++ method calls.'''

    def __init__(self, **kw):
        self.namespace = kw.pop('namespace', [])
        self.templates = kw.pop('templates', [])
        self.args = kw.pop('args', [])
        super(MethodCall, self).__init__(**kw)

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

    def argument(self, loader, indent):
        return self.call(loader, indent)


class Vector(MethodCall):
    '''Convenience type for vectors.'''

    def __init__(self, **kw):
        kw['name'] = 'vector'
        kw['namespace'] = ['std']
        kw['args'] = [InitializerList(values=kw.pop('args'))]
        super(Vector, self).__init__(**kw)


class Filter(MethodCall):
    '''Convenience type for filters'''

    def __init__(self, **kw):
        kw['name'] = 'make_filter'
        super(Filter, self).__init__(**kw)


class Action(MethodCall):
    '''Convenience type for actions'''

    def __init__(self, **kw):
        kw['name'] = 'make_action'
        super(Action, self).__init__(**kw)


class PathCondition(MethodCall):
    '''Convenience type for path conditions'''

    def __init__(self, **kw):
        kw['name'] = 'make_path_condition'
        super(PathCondition, self).__init__(**kw)


class GetProperty(MethodCall):
    '''Convenience type for getting inventory properties'''

    def __init__(self, **kw):
        kw['name'] = 'make_get_property'
        super(GetProperty, self).__init__(**kw)


class CreateObjects(MethodCall):
    '''Assemble a createObjects functor.'''

    def __init__(self, **kw):
        objs = []

        for path, interfaces in kw.pop('objs').iteritems():
            key_o = TrivialArgument(
                value=path,
                type='string',
                decorators=[Literal('string')])
            value_i = []

            for interface, properties, in interfaces.iteritems():
                key_i = TrivialArgument(value=interface, type='string')
                value_p = []
                if properties:
                    for prop, value in properties.iteritems():
                        key_p = TrivialArgument(value=prop, type='string')
                        value_v = TrivialArgument(
                            decorators=[Literal(value.get('type', None))],
                            **value)
                        value_p.append(InitializerList(values=[key_p, value_v]))

                value_p = InitializerList(values=value_p)
                value_i.append(InitializerList(values=[key_i, value_p]))

            value_i = InitializerList(values=value_i)
            objs.append(InitializerList(values=[key_o, value_i]))

        kw['args'] = [InitializerList(values=objs)]
        kw['namespace'] = ['functor']
        super(CreateObjects, self).__init__(**kw)


class DestroyObjects(MethodCall):
    '''Assemble a destroyObject functor.'''

    def __init__(self, **kw):
        values = [{'value': x, 'type': 'string'} for x in kw.pop('paths')]
        conditions = [
            Event.functor_map[
                x['name']](**x) for x in kw.pop('conditions', [])]
        conditions = [PathCondition(args=[x]) for x in conditions]
        args = [InitializerList(
            values=[TrivialArgument(**x) for x in values])]
        args.append(InitializerList(values=conditions))
        kw['args'] = args
        kw['namespace'] = ['functor']
        super(DestroyObjects, self).__init__(**kw)


class SetProperty(MethodCall):
    '''Assemble a setProperty functor.'''

    def __init__(self, **kw):
        args = []

        value = kw.pop('value')
        prop = kw.pop('property')
        iface = kw.pop('interface')
        iface = Interface(iface)
        namespace = iface.namespace().split('::')[:-1]
        name = iface[-1]
        t = Template(namespace=namespace, name=iface[-1])

        member = '&%s' % '::'.join(
            namespace + [name, NamedElement(name=prop).camelCase])
        member_type = cppTypeName(value['type'])
        member_cast = '{0} ({1}::*)({0})'.format(member_type, t.qualified())

        paths = [{'value': x, 'type': 'string'} for x in kw.pop('paths')]
        args.append(InitializerList(
            values=[TrivialArgument(**x) for x in paths]))

        conditions = [
            Event.functor_map[
                x['name']](**x) for x in kw.pop('conditions', [])]
        conditions = [PathCondition(args=[x]) for x in conditions]

        args.append(InitializerList(values=conditions))
        args.append(TrivialArgument(value=str(iface), type='string'))
        args.append(TrivialArgument(
            value=member, decorators=[Cast('static', member_cast)]))
        args.append(TrivialArgument(**value))

        kw['templates'] = [Template(name=name, namespace=namespace)]
        kw['args'] = args
        kw['namespace'] = ['functor']
        super(SetProperty, self).__init__(**kw)


class PropertyChanged(MethodCall):
    '''Assemble a propertyChanged functor.'''

    def __init__(self, **kw):
        args = []
        args.append(TrivialArgument(value=kw.pop('interface'), type='string'))
        args.append(TrivialArgument(value=kw.pop('property'), type='string'))
        args.append(TrivialArgument(
            decorators=[
                Literal(kw['value'].get('type', None))], **kw.pop('value')))
        kw['args'] = args
        kw['namespace'] = ['functor']
        super(PropertyChanged, self).__init__(**kw)


class PropertyIs(MethodCall):
    '''Assemble a propertyIs functor.'''

    def __init__(self, **kw):
        args = []
        path = kw.pop('path', None)
        if not path:
            path = TrivialArgument(value='nullptr')
        else:
            path = TrivialArgument(value=path, type='string')

        args.append(path)
        iface = TrivialArgument(value=kw.pop('interface'), type='string')
        args.append(iface)
        prop = TrivialArgument(value=kw.pop('property'), type='string')
        args.append(prop)
        args.append(TrivialArgument(
            decorators=[
                Literal(kw['value'].get('type', None))], **kw.pop('value')))

        service = kw.pop('service', None)
        if service:
            args.append(TrivialArgument(value=service, type='string'))

        dbusMember = kw.pop('dbusMember', None)
        if dbusMember:
            # Inventory manager's service name is required
            if not service or service != busname:
                args.append(TrivialArgument(value=busname, type='string'))

            gpArgs = []
            gpArgs.append(path)
            gpArgs.append(iface)
            # Prepend '&' and append 'getPropertyByName' function on dbusMember
            gpArgs.append(TrivialArgument(
                value='&'+dbusMember+'::getPropertyByName'))
            gpArgs.append(prop)
            fArg = MethodCall(
                name='getProperty',
                namespace=['functor'],
                templates=[Template(
                    name=dbusMember,
                    namespace=[])],
                args=gpArgs)

            # Append getProperty functor
            args.append(GetProperty(
                templates=[Template(
                    name=dbusMember+'::PropertiesVariant',
                    namespace=[])],
                    args=[fArg]))

        kw['args'] = args
        kw['namespace'] = ['functor']
        super(PropertyIs, self).__init__(**kw)


class Event(MethodCall):
    '''Assemble an inventory manager event.'''

    functor_map = {
        'destroyObjects': DestroyObjects,
        'createObjects': CreateObjects,
        'propertyChangedTo': PropertyChanged,
        'propertyIs': PropertyIs,
        'setProperty': SetProperty,
    }

    def __init__(self, **kw):
        self.summary = kw.pop('name')

        filters = [
            self.functor_map[x['name']](**x) for x in kw.pop('filters', [])]
        filters = [Filter(args=[x]) for x in filters]
        filters = Vector(
            templates=[Template(name='Filter', namespace=[])],
            args=filters)

        event = MethodCall(
            name='make_shared',
            namespace=['std'],
            templates=[Template(
                name=kw.pop('event'),
                namespace=kw.pop('event_namespace', []))],
            args=kw.pop('event_args', []) + [filters])

        events = Vector(
            templates=[Template(name='EventBasePtr', namespace=[])],
            args=[event])

        action_type = Template(name='Action', namespace=[])
        action_args = [
            self.functor_map[x['name']](**x) for x in kw.pop('actions', [])]
        action_args = [Action(args=[x]) for x in action_args]
        actions = Vector(
            templates=[action_type],
            args=action_args)

        kw['name'] = 'make_tuple'
        kw['namespace'] = ['std']
        kw['args'] = [events, actions]
        super(Event, self).__init__(**kw)


class MatchEvent(Event):
    '''Associate one or more dbus signal match signatures with
    a filter.'''

    def __init__(self, **kw):
        kw['event'] = 'DbusSignal'
        kw['event_namespace'] = []
        kw['event_args'] = [
            DbusSignature(**x) for x in kw.pop('signatures', [])]

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


class StartupEvent(Event):
    '''Assemble a startup event.'''

    def __init__(self, **kw):
        kw['event'] = 'StartupEvent'
        kw['event_namespace'] = []
        super(StartupEvent, self).__init__(**kw)


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

    class_map = {
        'match': MatchEvent,
        'startup': StartupEvent,
    }

    @staticmethod
    def load(args):
        # Aggregate all the event YAML in the events.d directory
        # into a single list of events.

        events = []
        events_dir = os.path.join(args.inputdir, 'events.d')

        if os.path.exists(events_dir):
            yaml_files = filter(
                lambda x: x.endswith('.yaml'),
                os.listdir(events_dir))

            for x in yaml_files:
                with open(os.path.join(events_dir, x), 'r') as fd:
                    for e in yaml.safe_load(fd.read()).get('events', {}):
                        events.append(e)

        interfaces, interface_composite = Everything.get_interfaces(
            args.ifacesdir)
        extra_interfaces, extra_interface_composite = \
            Everything.get_interfaces(
                os.path.join(args.inputdir, 'extra_interfaces.d'))
        interface_composite.update(extra_interface_composite)
        interface_composite = InterfaceComposite(interface_composite)
        # Update busname if configured differenly than the default
        busname = args.busname

        return Everything(
            *events,
            interfaces=interfaces + extra_interfaces,
            interface_composite=interface_composite)

    @staticmethod
    def get_interfaces(targetdir):
        '''Scan the interfaces directory for interfaces that PIM can create.'''

        yaml_files = []
        interfaces = []
        interface_composite = {}

        if targetdir and os.path.exists(targetdir):
            for directory, _, files in os.walk(targetdir):
                if not files:
                    continue

                yaml_files += map(
                    lambda f: os.path.relpath(
                        os.path.join(directory, f),
                        targetdir),
                    filter(lambda f: f.endswith('.interface.yaml'), files))

        for y in yaml_files:
            # parse only phosphor dbus related interface files
            if not y.startswith('xyz'):
                continue
            with open(os.path.join(targetdir, y)) as fd:
                i = y.replace('.interface.yaml', '').replace(os.sep, '.')

                # PIM can't create interfaces with methods.
                parsed = yaml.safe_load(fd.read())
                if parsed.get('methods', None):
                    continue
                # Cereal can't understand the type sdbusplus::object_path. This
                # type is a wrapper around std::string. Ignore interfaces having
                # a property of this type for now. The only interface that has a
                # property of this type now is xyz.openbmc_project.Association,
                # which is an unused interface. No inventory objects implement
                # this interface.
                # TODO via openbmc/openbmc#2123 : figure out how to make Cereal
                # understand sdbusplus::object_path.
                properties = parsed.get('properties', None)
                if properties:
                    if any('path' in p['type'] for p in properties):
                        continue
                interface_composite[i] = properties
                interfaces.append(i)

        return interfaces, interface_composite

    def __init__(self, *a, **kw):
        self.interfaces = \
            [Interface(x) for x in kw.pop('interfaces', [])]
        self.interface_composite = \
            kw.pop('interface_composite', {})
        self.events = [
            self.class_map[x['type']](**x) for x in a]
        super(Everything, self).__init__(**kw)

    def generate_cpp(self, loader):
        '''Render the template with the provided events and interfaces.'''
        with open(os.path.join(
                args.outputdir,
                'generated.cpp'), 'w') as fd:
            fd.write(
                self.render(
                    loader,
                    'generated.mako.cpp',
                    events=self.events,
                    interfaces=self.interfaces,
                    indent=Indent()))

    def generate_serialization(self, loader):
        with open(os.path.join(
                args.outputdir,
                'gen_serialization.hpp'), 'w') as fd:
            fd.write(
                self.render(
                    loader,
                    'gen_serialization.mako.hpp',
                    interfaces=self.interfaces,
                    interface_composite=self.interface_composite))


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

    parser = argparse.ArgumentParser(
        description='Phosphor Inventory Manager (PIM) YAML '
        'scanner and code generator.')
    parser.add_argument(
        '-o', '--output-dir', dest='outputdir',
        default='.', help='Output directory.')
    parser.add_argument(
        '-i', '--interfaces-dir', dest='ifacesdir',
        help='Location of interfaces to be supported.')
    parser.add_argument(
        '-d', '--dir', dest='inputdir',
        default=os.path.join(script_dir, 'example'),
        help='Location of files to process.')
    parser.add_argument(
        '-b', '--bus-name', dest='busname',
        default='xyz.openbmc_project.Inventory.Manager',
        help='Inventory manager busname.')
    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=[script_dir],
            disable_unicode=True)
    else:
        lookup = mako.lookup.TemplateLookup(
            directories=[script_dir])

    function = getattr(
        Everything.load(args),
        valid_commands[args.command])
    function(lookup)


# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
