#!/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 properties(self, interface):
        return self.dict[interface]

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

    def names(self, interface):
        names = []
        if self.dict[interface]:
            names = [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
