Api changes in AddReportFuture version

Added support for CollectionFunction, CollectionDuration,
CollectionTimeScope, ReportUpdates, AppendLimit.

New API separates Id and Name, user can decide to pass only Name
to auto generate Id or pass Id which needs to be unique.

Tested:
- No functional changes to old API, everything works as before
- All use cases can be replaced with new API to achieve same results
- New features which require new API work as expected

Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
Change-Id: I647efab36d90a548754f89968223e162a087481e
diff --git a/src/utils/conversion.hpp b/src/utils/conversion.hpp
index 222b990..fd3dbcb 100644
--- a/src/utils/conversion.hpp
+++ b/src/utils/conversion.hpp
@@ -1,5 +1,7 @@
 #pragma once
 
+#include <sdbusplus/exception.hpp>
+
 #include <algorithm>
 #include <array>
 #include <stdexcept>
@@ -13,7 +15,9 @@
 {
     [[noreturn]] static void throwConversionError()
     {
-        throw std::out_of_range("Value is not in range of enum");
+        throw sdbusplus::exception::SdBusError(
+            static_cast<int>(std::errc::invalid_argument),
+            "Invalid enum value");
     }
 };
 
diff --git a/src/utils/conversion_trigger.cpp b/src/utils/conversion_trigger.cpp
index aec0f28..ab06a48 100644
--- a/src/utils/conversion_trigger.cpp
+++ b/src/utils/conversion_trigger.cpp
@@ -73,7 +73,7 @@
     return utils::transform(infos, [](const LabeledSensorInfo& val) {
         return SensorsInfo::value_type(
             sdbusplus::message::object_path(val.at_label<ts::SensorPath>()),
-            val.at_label<ts::SensorMetadata>());
+            val.at_label<ts::Metadata>());
     });
 }
 
diff --git a/src/utils/generate_id.cpp b/src/utils/generate_id.cpp
new file mode 100644
index 0000000..adb1a5b
--- /dev/null
+++ b/src/utils/generate_id.cpp
@@ -0,0 +1,64 @@
+#include "utils/generate_id.hpp"
+
+#include <sdbusplus/exception.hpp>
+
+#include <system_error>
+
+namespace utils
+{
+namespace details
+{
+
+static constexpr std::string_view allowedCharactersInId =
+    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_/";
+
+}
+
+void verifyIdCharacters(std::string_view triggerId)
+{
+    if (triggerId.find_first_not_of(details::allowedCharactersInId) !=
+        std::string::npos)
+    {
+        throw sdbusplus::exception::SdBusError(
+            static_cast<int>(std::errc::invalid_argument),
+            "Invalid character in id");
+    }
+}
+
+std::string generateId(std::string_view prefix, std::string_view name,
+                       const std::vector<std::string>& conflictIds,
+                       size_t maxLength)
+{
+    verifyIdCharacters(prefix);
+
+    if (!prefix.empty() && !prefix.ends_with('/'))
+    {
+        return std::string(prefix);
+    }
+
+    std::string strippedId(name);
+    strippedId.erase(
+        std::remove_if(strippedId.begin(), strippedId.end(),
+                       [](char c) {
+                           return c == '/' ||
+                                  details::allowedCharactersInId.find(c) ==
+                                      std::string_view::npos;
+                       }),
+        strippedId.end());
+    strippedId = std::string(prefix) + strippedId;
+
+    size_t idx = 0;
+    std::string tmpId = strippedId.substr(0, maxLength);
+
+    while (std::find(conflictIds.begin(), conflictIds.end(), tmpId) !=
+               conflictIds.end() ||
+           tmpId.empty())
+    {
+        tmpId = strippedId.substr(0, maxLength - std::to_string(idx).length()) +
+                std::to_string(idx);
+        ++idx;
+    }
+    return tmpId;
+}
+
+} // namespace utils
diff --git a/src/utils/generate_id.hpp b/src/utils/generate_id.hpp
new file mode 100644
index 0000000..aa9508e
--- /dev/null
+++ b/src/utils/generate_id.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <string>
+#include <string_view>
+#include <vector>
+
+namespace utils
+{
+
+void verifyIdCharacters(std::string_view triggerId);
+std::string generateId(std::string_view prefix, std::string_view triggerName,
+                       const std::vector<std::string>& conflictIds,
+                       size_t maxLength);
+
+} // namespace utils
diff --git a/src/utils/labeled_tuple.hpp b/src/utils/labeled_tuple.hpp
index 398e4be..55789e9 100644
--- a/src/utils/labeled_tuple.hpp
+++ b/src/utils/labeled_tuple.hpp
@@ -167,6 +167,8 @@
         }
         else
         {
+            static_assert(Idx + 1 < sizeof...(Args),
+                          "Label not found in LabeledTuple");
             return find_item<Idx + 1, Label>(self);
         }
     }
diff --git a/src/utils/tstring.hpp b/src/utils/tstring.hpp
index f0bc679..e4529d8 100644
--- a/src/utils/tstring.hpp
+++ b/src/utils/tstring.hpp
@@ -24,11 +24,11 @@
     }
 };
 
-struct SensorMetadata
+struct Metadata
 {
     static std::string str()
     {
-        return "sensorMetadata";
+        return "metadata";
     }
 };
 
@@ -40,14 +40,6 @@
     }
 };
 
-struct MetricMetadata
-{
-    static std::string str()
-    {
-        return "metricMetadata";
-    }
-};
-
 struct Service
 {
     static std::string str()