#!/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


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 Argument(sdbusplus.property.Property):
    '''Bridge sdbusplus property typenames to syntatically correct c++.'''

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

    def cppArg(self):
        '''Transform string types to c++ string constants.'''
        if self.typeName == 'string':
            return '"%s"' % self.value

        return self.value


class MethodCall(NamedElement, Renderer):
    '''Render syntatically correct c++ method calls.'''

    def __init__(self, **kw):
        self.namespace = kw.pop('namespace', [])
        self.pointer = kw.pop('pointer', False)
        self.args = \
            [Argument(**x) for x in kw.pop('args', [])]
        super(MethodCall, self).__init__(**kw)

    def bare_method(self):
        '''Provide the method name and encompassing
        namespace without any arguments.'''
        return '::'.join(self.namespace + [self.name])


class Filter(MethodCall):
    '''Provide common attributes for any filter.'''

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


class Action(MethodCall):
    '''Provide common attributes for any action.'''

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


class DbusSignature(NamedElement, Renderer):
    '''Represent a dbus signal match signature.'''

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


class DestroyObject(Action):
    '''Render a destroyObject action.'''

    def __init__(self, **kw):
        mapped = kw.pop('args')
        kw['args'] = [
            {'value': mapped['path'], 'type':'string'},
        ]
        super(DestroyObject, self).__init__(**kw)


class NoopAction(Action):
    '''Render a noop action.'''

    def __init__(self, **kw):
        kw['pointer'] = True
        super(NoopAction, self).__init__(**kw)


class NoopFilter(Filter):
    '''Render a noop filter.'''

    def __init__(self, **kw):
        kw['pointer'] = True
        super(NoopFilter, self).__init__(**kw)


class PropertyChanged(Filter):
    '''Render a propertyChanged filter.'''

    def __init__(self, **kw):
        mapped = kw.pop('args')
        kw['args'] = [
            {'value': mapped['interface'], 'type':'string'},
            {'value': mapped['property'], 'type':'string'},
            mapped['value']
        ]
        super(PropertyChanged, self).__init__(**kw)


class Event(NamedElement, Renderer):
    '''Render an inventory manager event.'''

    action_map = {
        'noop': NoopAction,
        'destroyObject': DestroyObject,
    }

    def __init__(self, **kw):
        self.cls = kw.pop('type')
        self.actions = \
            [self.action_map[x['name']](**x)
                for x in kw.pop('actions', [{'name': 'noop'}])]
        super(Event, self).__init__(**kw)


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

    filter_map = {
        'none': NoopFilter,
        'propertyChangedTo': PropertyChanged,
    }

    def __init__(self, **kw):
        self.signatures = \
            [DbusSignature(**x) for x in kw.pop('signatures', [])]
        self.filters = \
            [self.filter_map[x['name']](**x)
                for x in kw.pop('filters', [{'name': 'none'}])]
        super(MatchEvent, self).__init__(**kw)


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

    class_map = {
        'match': MatchEvent,
    }

    @staticmethod
    def load(args):
        # Invoke sdbus++ to generate any extra interface bindings for
        # extra interfaces that aren't defined externally.
        yaml_files = []
        extra_ifaces_dir = os.path.join(args.inputdir, 'extra_interfaces.d')
        if os.path.exists(extra_ifaces_dir):
            for directory, _, files in os.walk(extra_ifaces_dir):
                if not files:
                    continue

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

        genfiles = {
            'server-cpp': lambda x: '%s.cpp' % (
                x.replace(os.sep, '.')),
            'server-header': lambda x: os.path.join(
                os.path.join(
                    *x.split('.')), 'server.hpp')
        }

        for i in yaml_files:
            iface = i.replace('.interface.yaml', '').replace(os.sep, '.')
            for process, f in genfiles.iteritems():

                dest = os.path.join(args.outputdir, f(iface))
                parent = os.path.dirname(dest)
                if parent and not os.path.exists(parent):
                    os.makedirs(parent)

                with open(dest, 'w') as fd:
                    subprocess.call([
                        'sdbus++',
                        '-r',
                        extra_ifaces_dir,
                        'interface',
                        process,
                        iface],
                        stdout=fd)

        # Aggregate all the event YAML in the events.d directory
        # into a single list of events.

        events_dir = os.path.join(args.inputdir, 'events.d')
        yaml_files = filter(
            lambda x: x.endswith('.yaml'),
            os.listdir(events_dir))

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

        return Everything(
            *events,
            interfaces=Everything.get_interfaces(args))

    @staticmethod
    def get_interfaces(args):
        '''Aggregate all the interface YAML in the interfaces.d
        directory into a single list of interfaces.'''

        interfaces_dir = os.path.join(args.inputdir, 'interfaces.d')
        yaml_files = filter(
            lambda x: x.endswith('.yaml'),
            os.listdir(interfaces_dir))

        interfaces = []
        for x in yaml_files:
            with open(os.path.join(interfaces_dir, x), 'r') as fd:
                for i in yaml.load(fd.read()):
                    interfaces.append(i)

        return interfaces

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

    def list_interfaces(self, *a):
        print ' '.join([str(i) for i in self.interfaces])

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


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

    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(
        '-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='Command to run.')

    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
