Add Unit Test for TemplateCharReplace

We keep finding issues in this function, add some tests.

Tested: The tests pass, this is mostly just moving the
code into a header. One test didn't work, but it didn't
work before either. It will be fixed later

Change-Id: I3eb60960104e861b0a0313580dc90bfb12051829
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/src/EntityManager.cpp b/src/EntityManager.cpp
index f135c20..25cc86c 100644
--- a/src/EntityManager.cpp
+++ b/src/EntityManager.cpp
@@ -16,6 +16,8 @@
 
 #include "EntityManager.hpp"
 
+#include "VariantVisitors.hpp"
+
 #include <Overlay.hpp>
 #include <Utils.hpp>
 #include <VariantVisitors.hpp>
@@ -26,7 +28,6 @@
 #include <boost/algorithm/string/split.hpp>
 #include <boost/container/flat_map.hpp>
 #include <boost/container/flat_set.hpp>
-#include <boost/lexical_cast.hpp>
 #include <boost/range/iterator_range.hpp>
 #include <filesystem>
 #include <fstream>
@@ -43,7 +44,6 @@
 constexpr const char* lastConfiguration = "/tmp/configuration/last.json";
 constexpr const char* currentConfiguration = "/var/configuration/system.json";
 constexpr const char* globalSchema = "global.json";
-constexpr const char* templateChar = "$";
 constexpr const int32_t MAX_MAPPER_DEPTH = 0;
 
 constexpr const bool DEBUG = false;
@@ -82,10 +82,6 @@
     std::variant<std::vector<std::string>, std::vector<double>, std::string,
                  int64_t, uint64_t, double, int32_t, uint32_t, int16_t,
                  uint16_t, uint8_t, bool>;
-using BasicVariantType =
-    std::variant<std::string, int64_t, uint64_t, double, int32_t, uint32_t,
-                 int16_t, uint16_t, uint8_t, bool>;
-
 using GetSubTreeType = std::vector<
     std::pair<std::string,
               std::vector<std::pair<std::string, std::vector<std::string>>>>>;
@@ -1124,216 +1120,6 @@
     }
 }
 
-// finds the template character (currently set to $) and replaces the value with
-// the field found in a dbus object i.e. $ADDRESS would get populated with the
-// ADDRESS field from a object on dbus
-void templateCharReplace(
-    nlohmann::json::iterator& keyPair,
-    const boost::container::flat_map<std::string, BasicVariantType>&
-        foundDevice,
-    size_t& foundDeviceIdx)
-{
-    if (keyPair.value().type() == nlohmann::json::value_t::object ||
-        keyPair.value().type() == nlohmann::json::value_t::array)
-    {
-        for (auto nextLayer = keyPair.value().begin();
-             nextLayer != keyPair.value().end(); nextLayer++)
-        {
-            templateCharReplace(nextLayer, foundDevice, foundDeviceIdx);
-        }
-        return;
-    }
-
-    std::string* strPtr = keyPair.value().get_ptr<std::string*>();
-    if (strPtr == nullptr)
-    {
-        return;
-    }
-
-    boost::replace_all(*strPtr, std::string(templateChar) + "index",
-                       std::to_string(foundDeviceIdx));
-
-    for (auto& foundDevicePair : foundDevice)
-    {
-        std::string templateName = templateChar + foundDevicePair.first;
-        boost::iterator_range<std::string::const_iterator> find =
-            boost::ifind_first(*strPtr, templateName);
-        if (find)
-        {
-            size_t start = find.begin() - strPtr->begin();
-            // check for additional operations
-            if (find.end() == strPtr->end())
-            {
-                std::visit([&](auto&& val) { keyPair.value() = val; },
-                           foundDevicePair.second);
-                return;
-            }
-
-            // save the prefix
-            std::string prefix = strPtr->substr(0, start);
-
-            // operate on the rest (+1 for trailing space)
-            std::string end = strPtr->substr(start + templateName.size() + 1);
-
-            std::vector<std::string> split;
-            boost::split(split, end, boost::is_any_of(" "));
-
-            // need at least 1 operation and number
-            if (split.size() < 2)
-            {
-                std::cerr << "Syntax error on template replacement of "
-                          << *strPtr << "\n";
-                for (const std::string& data : split)
-                {
-                    std::cerr << data << " ";
-                }
-                std::cerr << "\n";
-                continue;
-            }
-
-            // we assume that the replacement is a number, because we can
-            // only do math on numbers.. we might concatenate strings in the
-            // future, but thats later
-            int number =
-                std::visit(VariantToIntVisitor(), foundDevicePair.second);
-
-            bool isOperator = true;
-            TemplateOperation next = TemplateOperation::addition;
-
-            auto it = split.begin();
-
-            for (; it != split.end(); it++)
-            {
-                if (isOperator)
-                {
-                    if (*it == "+")
-                    {
-                        next = TemplateOperation::addition;
-                    }
-                    else if (*it == "-")
-                    {
-                        next = TemplateOperation::subtraction;
-                    }
-                    else if (*it == "*")
-                    {
-                        next = TemplateOperation::multiplication;
-                    }
-                    else if (*it == R"(%)")
-                    {
-                        next = TemplateOperation::modulo;
-                    }
-                    else if (*it == R"(/)")
-                    {
-                        next = TemplateOperation::division;
-                    }
-                    else
-                    {
-                        break;
-                    }
-                }
-                else
-                {
-                    int constant = 0;
-                    try
-                    {
-                        constant = std::stoi(*it);
-                    }
-                    catch (std::invalid_argument&)
-                    {
-                        std::cerr << "Parameter not supported for templates "
-                                  << *it << "\n";
-                        continue;
-                    }
-                    switch (next)
-                    {
-                        case TemplateOperation::addition:
-                        {
-                            number += constant;
-                            break;
-                        }
-                        case TemplateOperation::subtraction:
-                        {
-                            number -= constant;
-                            break;
-                        }
-                        case TemplateOperation::multiplication:
-                        {
-                            number *= constant;
-                            break;
-                        }
-                        case TemplateOperation::division:
-                        {
-                            number /= constant;
-                            break;
-                        }
-                        case TemplateOperation::modulo:
-                        {
-                            number = number % constant;
-                            break;
-                        }
-
-                        default:
-                            break;
-                    }
-                }
-                isOperator = !isOperator;
-            }
-            std::string result = prefix + std::to_string(number);
-
-            if (it != split.end())
-            {
-                for (; it != split.end(); it++)
-                {
-                    result += " " + *it;
-                }
-            }
-            keyPair.value() = result;
-
-            // We probably just invalidated the pointer above, so set it to null
-            strPtr = nullptr;
-            break;
-        }
-    }
-
-    strPtr = keyPair.value().get_ptr<std::string*>();
-    if (strPtr == nullptr)
-    {
-        return;
-    }
-
-    // convert hex numbers to ints
-    if (boost::starts_with(*strPtr, "0x"))
-    {
-        try
-        {
-            size_t pos = 0;
-            int64_t temp = std::stoul(*strPtr, &pos, 0);
-            if (pos == strPtr->size())
-            {
-                keyPair.value() = static_cast<uint64_t>(temp);
-            }
-        }
-        catch (std::invalid_argument&)
-        {
-        }
-        catch (std::out_of_range&)
-        {
-        }
-    }
-    // non-hex numbers
-    else
-    {
-        try
-        {
-            uint64_t temp = boost::lexical_cast<uint64_t>(*strPtr);
-            keyPair.value() = temp;
-        }
-        catch (boost::bad_lexical_cast&)
-        {
-        }
-    }
-}
-
 // reads json files out of the filesystem
 bool findJsonFiles(std::list<nlohmann::json>& configurations)
 {