#!/usr/bin/env python3

"""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 argparse
import os
import sys

import mako.lookup
import sdbusplus.property
import yaml
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 list(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.items()}
        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").items():
            key_o = TrivialArgument(
                value=path, type="string", decorators=[Literal("string")]
            )
            value_i = []

            for (
                interface,
                properties,
            ) in interfaces.items():
                key_i = TrivialArgument(value=interface, type="string")
                value_p = []
                if properties:
                    for prop, value in properties.items():
                        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 = [
                x for x in os.listdir(events_dir) if x.endswith(".yaml")
            ]

            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
        global busname
        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 += [
                    os.path.relpath(os.path.join(directory, f), targetdir)
                    for f in [
                        f for f in files if f.endswith(".interface.yaml")
                    ]
                ]

        for y in yaml_files:
            # parse only phosphor dbus related interface files
            if not (
                y.startswith("xyz")
                or y.startswith("com/ibm/ipzvpd")
                or y.startswith("com/ibm/Control/Host")
            ):
                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=list(valid_commands.keys()),
        help="%s." % " | ".join(list(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)
