Add array patching support

Stepwise controllers use arrays so these will need
to be persisted.

Tested: Patched stepwise controller in redfish and
json was updated

Change-Id: If8a59a3a2f4b759f8a3d245c663ced81d68316d6
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/src/EntityManager.cpp b/src/EntityManager.cpp
index b28dc9a..35fadb9 100644
--- a/src/EntityManager.cpp
+++ b/src/EntityManager.cpp
@@ -515,27 +515,6 @@
     return true;
 }
 
-// template function to add array as dbus property
-template <typename PropertyType>
-void addArrayToDbus(const std::string& name, const nlohmann::json& array,
-                    sdbusplus::asio::dbus_interface* iface,
-                    sdbusplus::asio::PropertyPermission permission)
-{
-    std::vector<PropertyType> values;
-    for (const auto& property : array)
-    {
-        auto ptr = property.get_ptr<const PropertyType*>();
-        if (ptr != nullptr)
-        {
-            values.emplace_back(*ptr);
-        }
-    }
-    // todo(james), currently there are no reason to persist arrays, get around
-    // to it if needed
-
-    iface->register_property(name, values, permission);
-}
-
 template <typename JsonType>
 bool setJsonFromPointer(const std::string& ptrStr, const JsonType& value,
                         nlohmann::json& systemConfiguration)
@@ -553,6 +532,53 @@
     }
 }
 
+// template function to add array as dbus property
+template <typename PropertyType>
+void addArrayToDbus(const std::string& name, const nlohmann::json& array,
+                    sdbusplus::asio::dbus_interface* iface,
+                    sdbusplus::asio::PropertyPermission permission,
+                    nlohmann::json& systemConfiguration,
+                    const std::string& jsonPointerString)
+{
+    std::vector<PropertyType> values;
+    for (const auto& property : array)
+    {
+        auto ptr = property.get_ptr<const PropertyType*>();
+        if (ptr != nullptr)
+        {
+            values.emplace_back(*ptr);
+        }
+    }
+
+    if (permission == sdbusplus::asio::PropertyPermission::readOnly)
+    {
+        iface->register_property(name, values);
+    }
+    else
+    {
+        iface->register_property(
+            name, values,
+            [&systemConfiguration,
+             jsonPointerString{std::string(jsonPointerString)}](
+                const std::vector<PropertyType>& newVal,
+                std::vector<PropertyType>& val) {
+                val = newVal;
+                if (!setJsonFromPointer(jsonPointerString, val,
+                                        systemConfiguration))
+                {
+                    std::cerr << "error setting json field\n";
+                    return -1;
+                }
+                if (!writeJsonFiles(systemConfiguration))
+                {
+                    std::cerr << "error setting json file\n";
+                    return -1;
+                }
+                return 1;
+            });
+    }
+}
+
 template <typename PropertyType>
 void addProperty(const std::string& propertyName, const PropertyType& value,
                  sdbusplus::asio::dbus_interface* iface,
@@ -667,7 +693,14 @@
             // all setable numbers are doubles as it is difficult to always
             // create a configuration file with all whole numbers as decimals
             // i.e. 1.0
-            if (dictPair.value().is_number())
+            if (array)
+            {
+                if (dictPair.value()[0].is_number())
+                {
+                    type = nlohmann::json::value_t::number_float;
+                }
+            }
+            else if (dictPair.value().is_number())
             {
                 type = nlohmann::json::value_t::number_float;
             }
@@ -682,7 +715,8 @@
                     // todo: array of bool isn't detected correctly by
                     // sdbusplus, change it to numbers
                     addArrayToDbus<uint64_t>(dictPair.key(), dictPair.value(),
-                                             iface.get(), permission);
+                                             iface.get(), permission,
+                                             systemConfiguration, key);
                 }
 
                 else
@@ -698,7 +732,8 @@
                 if (array)
                 {
                     addArrayToDbus<int64_t>(dictPair.key(), dictPair.value(),
-                                            iface.get(), permission);
+                                            iface.get(), permission,
+                                            systemConfiguration, key);
                 }
                 else
                 {
@@ -713,7 +748,8 @@
                 if (array)
                 {
                     addArrayToDbus<uint64_t>(dictPair.key(), dictPair.value(),
-                                             iface.get(), permission);
+                                             iface.get(), permission,
+                                             systemConfiguration, key);
                 }
                 else
                 {
@@ -729,7 +765,8 @@
                 if (array)
                 {
                     addArrayToDbus<double>(dictPair.key(), dictPair.value(),
-                                           iface.get(), permission);
+                                           iface.get(), permission,
+                                           systemConfiguration, key);
                 }
 
                 else
@@ -744,9 +781,9 @@
             {
                 if (array)
                 {
-                    addArrayToDbus<std::string>(dictPair.key(),
-                                                dictPair.value(), iface.get(),
-                                                permission);
+                    addArrayToDbus<std::string>(
+                        dictPair.key(), dictPair.value(), iface.get(),
+                        permission, systemConfiguration, key);
                 }
                 else
                 {