Always fill both values for a threshold interface

If one of the thresholds for a threshold dbus interface is provided we
have to set the other one as dbus properties are never optional.

Tested:
  Before:
xyz.openbmc_project.Sensor.Threshold.Warning    interface -      -
.WarningAlarmHigh                               property  b      false
.WarningHigh                                    property  d      14

  After:
xyz.openbmc_project.Sensor.Threshold.Warning    interface -      -
.WarningAlarmHigh                               property  b      false
.WarningAlarmLow                                property  b      false
.WarningHigh                                    property  d      14
.WarningLow                                     property  d      nan

Signed-off-by: Konstantin Aladyshev <aladyshev22@gmail.com>
Change-Id: I0e9b885e8c0494d46d39af965047a7582255a48e
diff --git a/include/sensor.hpp b/include/sensor.hpp
index 2c7a020..23d5a76 100644
--- a/include/sensor.hpp
+++ b/include/sensor.hpp
@@ -255,6 +255,9 @@
             "Value", value, [&](const double& newValue, double& oldValue) {
                 return setSensorValue(newValue, oldValue);
             });
+
+        fillMissingThresholds();
+
         for (auto& threshold : thresholds)
         {
             if (std::isnan(threshold.hysteresis))
@@ -534,6 +537,41 @@
     }
 
   private:
+    // If one of the thresholds for a dbus interface is provided
+    // we have to set the other one as dbus properties are never
+    // optional.
+    void fillMissingThresholds()
+    {
+        for (thresholds::Threshold& thisThreshold : thresholds)
+        {
+            bool foundOpposite = false;
+            thresholds::Direction opposite = thresholds::Direction::HIGH;
+            if (thisThreshold.direction == thresholds::Direction::HIGH)
+            {
+                opposite = thresholds::Direction::LOW;
+            }
+            for (thresholds::Threshold& otherThreshold : thresholds)
+            {
+                if (thisThreshold.level != otherThreshold.level)
+                {
+                    continue;
+                }
+                if (otherThreshold.direction != opposite)
+                {
+                    continue;
+                }
+                foundOpposite = true;
+                break;
+            }
+            if (foundOpposite)
+            {
+                continue;
+            }
+            thresholds.emplace_back(thisThreshold.level, opposite,
+                                    std::numeric_limits<double>::quiet_NaN());
+        }
+    }
+
     void updateValueProperty(const double& newValue)
     {
         // Indicate that it is internal set call, not an external overwrite