sdbus++: events: generate markdown

Add enough content in event support to generate markdown documentation.

    - Create python-translation from event YAML to internal classes
      and call mako renders.
    - Add empty mako templates for the C++ files.
    - Add mako templates necessary to generate markdown content.

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Ifd4aa16895b2ed5f72b3bc74170c1c666e29b02e
diff --git a/tools/meson.build b/tools/meson.build
index ea17050..94a9f85 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -17,6 +17,12 @@
   'sdbusplus/templates/error.cpp.mako',
   'sdbusplus/templates/error.hpp.mako',
   'sdbusplus/templates/error.md.mako',
+  'sdbusplus/templates/event.cpp.mako',
+  'sdbusplus/templates/event.hpp.mako',
+  'sdbusplus/templates/event.md.mako',
+  'sdbusplus/templates/events.cpp.mako',
+  'sdbusplus/templates/events.hpp.mako',
+  'sdbusplus/templates/events.md.mako',
   'sdbusplus/templates/interface.aserver.hpp.mako',
   'sdbusplus/templates/interface.client.hpp.mako',
   'sdbusplus/templates/interface.common.hpp.mako',
diff --git a/tools/sdbusplus/event.py b/tools/sdbusplus/event.py
index d8b0ac5..dd343cf 100644
--- a/tools/sdbusplus/event.py
+++ b/tools/sdbusplus/event.py
@@ -7,6 +7,52 @@
 from .renderer import Renderer
 
 
+class EventMetadata(NamedElement):
+    def __init__(self, **kwargs):
+        self.type = kwargs.pop("type")
+        self.primary = kwargs.pop("primary", False)
+        super(EventMetadata, self).__init__(**kwargs)
+
+
+class EventLanguage(object):
+    def __init__(self, **kwargs):
+        super(EventLanguage, self).__init__()
+        self.description = kwargs.pop("description", False)
+        self.message = kwargs.pop("message")
+        self.resolution = kwargs.pop("resolution", False)
+
+
+class EventElement(NamedElement):
+    def __init__(self, **kwargs):
+        self.deprecated = kwargs.pop("deprecated", None)
+        self.errno = kwargs.pop("errno", None)
+        self.languages = {
+            key: EventLanguage(**kwargs.pop(key, {})) for key in ["en"]
+        }
+        self.metadata = [
+            EventMetadata(**n) for n in kwargs.pop("metadata", [])
+        ]
+        self.redfish_map = kwargs.pop("redfish-mapping", None)
+        self.severity = EventElement.syslog_severity(
+            kwargs.pop("severity", "informational")
+        )
+
+        super(EventElement, self).__init__(**kwargs)
+
+    @staticmethod
+    def syslog_severity(severity: str) -> str:
+        return {
+            "emergency": "LOG_EMERG",
+            "alert": "LOG_ALERT",
+            "critical": "LOG_CRIT",
+            "error": "LOG_ERR",
+            "warning": "LOG_WARNING",
+            "notice": "LOG_NOTICE",
+            "informational": "LOG_INFO",
+            "debug": "LOG_DEBUG",
+        }[severity]
+
+
 class Event(NamedElement, Renderer):
     @staticmethod
     def load(name, rootdir, schemadir):
@@ -34,13 +80,17 @@
             return Event(**y)
 
     def __init__(self, **kwargs):
+        self.version = kwargs.pop("version")
+        self.errors = [EventElement(**n) for n in kwargs.pop("errors", [])]
+        self.events = [EventElement(**n) for n in kwargs.pop("events", [])]
+
         super(Event, self).__init__(**kwargs)
 
     def markdown(self, loader):
-        return ""
+        return self.render(loader, "events.md.mako", events=self)
 
     def exception_header(self, loader):
-        return ""
+        return self.render(loader, "events.hpp.mako", events=self)
 
     def exception_cpp(self, loader):
-        return ""
+        return self.render(loader, "events.cpp.mako", events=self)
diff --git a/tools/sdbusplus/namedelement.py b/tools/sdbusplus/namedelement.py
index 2f332cb..87cb86d 100644
--- a/tools/sdbusplus/namedelement.py
+++ b/tools/sdbusplus/namedelement.py
@@ -27,6 +27,7 @@
             "CamelCase": lambda: inflection.camelize(self.name),
             "camelCase": lambda: NamedElement.lower_camel_case(self.name),
             "snake_case": lambda: inflection.underscore(self.name),
+            "SNAKE_CASE": lambda: inflection.underscore(self.name).upper(),
         }.get(name)
 
         if lam:
diff --git a/tools/sdbusplus/templates/event.cpp.mako b/tools/sdbusplus/templates/event.cpp.mako
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/sdbusplus/templates/event.cpp.mako
diff --git a/tools/sdbusplus/templates/event.hpp.mako b/tools/sdbusplus/templates/event.hpp.mako
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/sdbusplus/templates/event.hpp.mako
diff --git a/tools/sdbusplus/templates/event.md.mako b/tools/sdbusplus/templates/event.md.mako
new file mode 100644
index 0000000..012d833
--- /dev/null
+++ b/tools/sdbusplus/templates/event.md.mako
@@ -0,0 +1,25 @@
+${"####"} ${event.name}
+
+% if event.redfish_map:
+${event.redfish_map}
+% elif event.languages["en"].description:
+${event.languages["en"].description}
+% else:
+${event.languages["en"].message}
+% endif
+
+% if event.errno:
+- severity: `${event.severity}`
+- errno: `${event.errno}`
+% endif
+% if event.metadata:
+- metadata:
+% for m in event.metadata:
+  - `${m.SNAKE_CASE}` as `${m.type}` \
+% if m.primary:
+**[PRIMARY]**
+% else:
+
+% endif
+% endfor
+% endif
diff --git a/tools/sdbusplus/templates/events.cpp.mako b/tools/sdbusplus/templates/events.cpp.mako
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/sdbusplus/templates/events.cpp.mako
diff --git a/tools/sdbusplus/templates/events.hpp.mako b/tools/sdbusplus/templates/events.hpp.mako
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/sdbusplus/templates/events.hpp.mako
diff --git a/tools/sdbusplus/templates/events.md.mako b/tools/sdbusplus/templates/events.md.mako
new file mode 100644
index 0000000..af15e3b
--- /dev/null
+++ b/tools/sdbusplus/templates/events.md.mako
@@ -0,0 +1,18 @@
+${"##"} Events
+
+% if events.errors:
+${"###"} Errors
+
+% for e in events.errors:
+${events.render(loader, "event.md.mako", event=e)}
+% endfor
+
+% endif
+% if events.events:
+${"###"} Events
+
+% for e in events.events:
+${events.render(loader, "event.md.mako", event=e)}
+% endfor
+
+% endif