thresholds: Update Severity to be a string

Thresholds are now strings, so update to treat them as such. However
still accept unsigned ints for backwards compatibility.

Tested: Used both strings and unsigned ints in severity fields in a
virtual sensor config, and we see correct threshold properties and
behaviour.

Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
Change-Id: I893877a769eb81e6589ce42a01079816e5493b4f
diff --git a/README.md b/README.md
index b714da9..3de5b9e 100644
--- a/README.md
+++ b/README.md
@@ -28,14 +28,4 @@
 
 The virtual sensor configuration in entity manager follows a different format
 to the JSON in virtual_sensor_config.json (specified in
-entity-manager/schemas/VirtualSensor.json). In particular, the format for
-Thresholds is different. The following table shows the severity fields
-that correspond to a particular threshold.
-
-Threshold       | Severity
-----------------|-----------
-Warning         |     0
-Critical        |     1
-PerformanceLoss |     2
-SoftShutdown    |     3
-HardShutdown    |     4
+entity-manager/schemas/VirtualSensor.json).
diff --git a/virtualSensor.cpp b/virtualSensor.cpp
index 2efd867..33206e2 100644
--- a/virtualSensor.cpp
+++ b/virtualSensor.cpp
@@ -134,20 +134,9 @@
 }
 
 const std::string getThresholdType(const std::string& direction,
-                                   uint64_t severity)
+                                   const std::string& severity)
 {
-    std::string threshold;
     std::string suffix;
-    static const std::array thresholdTypes{"Warning", "Critical",
-                                           "PerformanceLoss", "SoftShutdown",
-                                           "HardShutdown"};
-
-    if (severity >= thresholdTypes.size())
-    {
-        throw std::invalid_argument(
-            "Invalid threshold severity specified in entity manager");
-    }
-    threshold = thresholdTypes[severity];
 
     if (direction == "less than")
     {
@@ -162,19 +151,54 @@
         throw std::invalid_argument(
             "Invalid threshold direction specified in entity manager");
     }
-    return threshold + suffix;
+    return severity + suffix;
+}
+
+std::string getSeverityField(const PropertyMap& propertyMap)
+{
+    static const std::array thresholdTypes{"Warning", "Critical",
+                                           "PerformanceLoss", "SoftShutdown",
+                                           "HardShutdown"};
+
+    std::string severity;
+    if (auto itr = propertyMap.find("Severity"); itr != propertyMap.end())
+    {
+        /* Severity should be a string, but can be an unsigned int */
+        if (std::holds_alternative<std::string>(itr->second))
+        {
+            severity = std::get<std::string>(itr->second);
+            if (0 == std::ranges::count(thresholdTypes, severity))
+            {
+                throw std::invalid_argument(
+                    "Invalid threshold severity specified in entity manager");
+            }
+        }
+        else
+        {
+            auto sev =
+                getNumberFromConfig<uint64_t>(propertyMap, "Severity", true);
+            /* Checking bounds ourselves so we throw invalid argument on
+             * invalid user input */
+            if (sev >= thresholdTypes.size())
+            {
+                throw std::invalid_argument(
+                    "Invalid threshold severity specified in entity manager");
+            }
+            severity = thresholdTypes.at(sev);
+        }
+    }
+    return severity;
 }
 
 void parseThresholds(Json& thresholds, const PropertyMap& propertyMap)
 {
     std::string direction;
 
-    auto severity =
-        getNumberFromConfig<uint64_t>(propertyMap, "Severity", true);
     auto value = getNumberFromConfig<double>(propertyMap, "Value", true);
 
-    auto itr = propertyMap.find("Direction");
-    if (itr != propertyMap.end())
+    auto severity = getSeverityField(propertyMap);
+
+    if (auto itr = propertyMap.find("Direction"); itr != propertyMap.end())
     {
         direction = std::get<std::string>(itr->second);
     }