Add Report interface to dbus

Added AddReport method to ReportManager to allow dbus user
to create new Report. Added Report object with Report and Delete
interfaces.

Tested:
 - Verified that telemetry service works in romulus
 - Added and removed report from ReportManager collection

Change-Id: Ib20cfda1f0e27ef20b60e66d52c3d11f31f61a96
Signed-off-by: Wludzik, Jozef <jozef.wludzik@intel.com>
diff --git a/src/report_manager.cpp b/src/report_manager.cpp
index 9735abd..f2cbe94 100644
--- a/src/report_manager.cpp
+++ b/src/report_manager.cpp
@@ -1,5 +1,7 @@
 #include "report_manager.hpp"
 
+#include <sdbusplus/exception.hpp>
+
 #include <system_error>
 
 constexpr const char* reportManagerIfaceName =
@@ -8,23 +10,68 @@
     "/xyz/openbmc_project/Telemetry/Reports";
 
 ReportManager::ReportManager(
-    const std::shared_ptr<sdbusplus::asio::object_server>& objServer) :
-    objServer(objServer)
+    const std::shared_ptr<sdbusplus::asio::connection>& bus,
+    const std::shared_ptr<sdbusplus::asio::object_server>& objServerIn) :
+    objServer(objServerIn)
 {
-    reportManagerIntf =
-        objServer->add_interface(reportManagerPath, reportManagerIfaceName);
+    reports.reserve(maxReports);
 
-    reportManagerIntf->register_property_r(
-        "MaxReports", uint32_t{}, sdbusplus::vtable::property_::const_,
-        [](const auto&) { return maxReports; });
-    reportManagerIntf->register_property_r(
-        "MinInterval", uint64_t{}, sdbusplus::vtable::property_::const_,
-        [](const auto&) -> uint64_t { return minInterval.count(); });
+    reportManagerIface = objServer->add_unique_interface(
+        reportManagerPath, reportManagerIfaceName,
+        [this, &ioc = bus->get_io_context()](auto& dbusIface) {
+            dbusIface.register_property_r(
+                "MaxReports", uint32_t{}, sdbusplus::vtable::property_::const_,
+                [](const auto&) { return maxReports; });
+            dbusIface.register_property_r(
+                "MinInterval", uint64_t{}, sdbusplus::vtable::property_::const_,
+                [](const auto&) -> uint64_t { return minInterval.count(); });
 
-    reportManagerIntf->initialize();
+            dbusIface.register_method(
+                "AddReport",
+                [this, &ioc](const std::string& reportName,
+                             const std::string& reportingType,
+                             const bool emitsReadingsUpdate,
+                             const bool logToMetricReportsCollection,
+                             const uint64_t interval,
+                             const ReadingParameters& metricParams) {
+                    if (reports.size() >= maxReports)
+                    {
+                        throw sdbusplus::exception::SdBusError(
+                            static_cast<int>(std::errc::too_many_files_open),
+                            "Reached maximal report count");
+                    }
+
+                    for (const auto& report : reports)
+                    {
+                        if (report->name == reportName)
+                        {
+                            throw sdbusplus::exception::SdBusError(
+                                static_cast<int>(std::errc::file_exists),
+                                "Duplicate report");
+                        }
+                    }
+
+                    std::chrono::milliseconds reportInterval{interval};
+                    if (reportInterval < minInterval)
+                    {
+                        throw sdbusplus::exception::SdBusError(
+                            static_cast<int>(std::errc::invalid_argument),
+                            "Invalid interval");
+                    }
+
+                    reports.emplace_back(std::make_unique<Report>(
+                        ioc, objServer, reportName, reportingType,
+                        emitsReadingsUpdate, logToMetricReportsCollection,
+                        std::move(reportInterval), metricParams, *this));
+                    return reports.back()->path;
+                });
+        });
 }
 
-ReportManager::~ReportManager()
+void ReportManager::removeReport(const Report* report)
 {
-    objServer->remove_interface(reportManagerIntf);
+    reports.erase(
+        std::remove_if(reports.begin(), reports.end(),
+                       [report](const auto& x) { return report == x.get(); }),
+        reports.end());
 }