// Copyright (c) 2018 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once
#include <crow/app.h>
#include <tinyxml2.h>

#include <async_resp.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/container/flat_set.hpp>
#include <dbus_singleton.hpp>
#include <dbus_utility.hpp>
#include <filesystem>
#include <fstream>
#include <regex>
#include <sdbusplus/message/types.hpp>

namespace crow
{
namespace openbmc_mapper
{

using GetSubTreeType = std::vector<
    std::pair<std::string,
              std::vector<std::pair<std::string, std::vector<std::string>>>>>;

const std::string notFoundMsg = "404 Not Found";
const std::string badReqMsg = "400 Bad Request";
const std::string methodNotAllowedMsg = "405 Method Not Allowed";
const std::string forbiddenMsg = "403 Forbidden";
const std::string methodFailedMsg = "500 Method Call Failed";
const std::string methodOutputFailedMsg = "500 Method Output Error";

const std::string notFoundDesc =
    "org.freedesktop.DBus.Error.FileNotFound: path or object not found";
const std::string propNotFoundDesc = "The specified property cannot be found";
const std::string noJsonDesc = "No JSON object could be decoded";
const std::string methodNotFoundDesc = "The specified method cannot be found";
const std::string methodNotAllowedDesc = "Method not allowed";
const std::string forbiddenPropDesc =
    "The specified property cannot be created";
const std::string forbiddenResDesc = "The specified resource cannot be created";

void setErrorResponse(crow::Response &res, boost::beast::http::status result,
                      const std::string &desc, const std::string &msg)
{
    res.result(result);
    res.jsonValue = {{"data", {{"description", desc}}},
                     {"message", msg},
                     {"status", "error"}};
}

void introspectObjects(const std::string &processName,
                       const std::string &objectPath,
                       std::shared_ptr<bmcweb::AsyncResp> transaction)
{
    if (transaction->res.jsonValue.is_null())
    {
        transaction->res.jsonValue = {{"status", "ok"},
                                      {"bus_name", processName},
                                      {"objects", nlohmann::json::array()}};
    }

    crow::connections::systemBus->async_method_call(
        [transaction, processName{std::string(processName)},
         objectPath{std::string(objectPath)}](
            const boost::system::error_code ec,
            const std::string &introspect_xml) {
            if (ec)
            {
                BMCWEB_LOG_ERROR
                    << "Introspect call failed with error: " << ec.message()
                    << " on process: " << processName << " path: " << objectPath
                    << "\n";
                return;
            }
            transaction->res.jsonValue["objects"].push_back(
                {{"path", objectPath}});

            tinyxml2::XMLDocument doc;

            doc.Parse(introspect_xml.c_str());
            tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
            if (pRoot == nullptr)
            {
                BMCWEB_LOG_ERROR << "XML document failed to parse "
                                 << processName << " " << objectPath << "\n";
            }
            else
            {
                tinyxml2::XMLElement *node = pRoot->FirstChildElement("node");
                while (node != nullptr)
                {
                    const char *childPath = node->Attribute("name");
                    if (childPath != nullptr)
                    {
                        std::string newpath;
                        if (objectPath != "/")
                        {
                            newpath += objectPath;
                        }
                        newpath += std::string("/") + childPath;
                        // introspect the subobjects as well
                        introspectObjects(processName, newpath, transaction);
                    }

                    node = node->NextSiblingElement("node");
                }
            }
        },
        processName, objectPath, "org.freedesktop.DBus.Introspectable",
        "Introspect");
}

void getPropertiesForEnumerate(const std::string &objectPath,
                               const std::string &service,
                               const std::string &interface,
                               std::shared_ptr<bmcweb::AsyncResp> asyncResp)
{
    BMCWEB_LOG_DEBUG << "getPropertiesForEnumerate " << objectPath << " "
                     << service << " " << interface;

    crow::connections::systemBus->async_method_call(
        [asyncResp, objectPath, service,
         interface](const boost::system::error_code ec,
                    const std::vector<
                        std::pair<std::string, dbus::utility::DbusVariantType>>
                        &propertiesList) {
            if (ec)
            {
                BMCWEB_LOG_ERROR << "GetAll on path " << objectPath << " iface "
                                 << interface << " service " << service
                                 << " failed with code " << ec;
                return;
            }

            nlohmann::json &dataJson = asyncResp->res.jsonValue["data"];
            nlohmann::json &objectJson = dataJson[objectPath];
            if (objectJson.is_null())
            {
                objectJson = nlohmann::json::object();
            }

            for (const auto &[name, value] : propertiesList)
            {
                nlohmann::json &propertyJson = objectJson[name];
                std::visit([&propertyJson](auto &&val) { propertyJson = val; },
                           value);
            }
        },
        service, objectPath, "org.freedesktop.DBus.Properties", "GetAll",
        interface);
}

// Find any results that weren't picked up by ObjectManagers, to be
// called after all ObjectManagers are searched for and called.
void findRemainingObjectsForEnumerate(
    const std::string &objectPath, std::shared_ptr<GetSubTreeType> subtree,
    std::shared_ptr<bmcweb::AsyncResp> asyncResp)
{
    BMCWEB_LOG_DEBUG << "findRemainingObjectsForEnumerate";
    const nlohmann::json &dataJson = asyncResp->res.jsonValue["data"];

    for (const auto &[path, interface_map] : *subtree)
    {
        if (path == objectPath)
        {
            // An enumerate does not return the target path's properties
            continue;
        }
        if (dataJson.find(path) == dataJson.end())
        {
            for (const auto &[service, interfaces] : interface_map)
            {
                for (const auto &interface : interfaces)
                {
                    if (!boost::starts_with(interface, "org.freedesktop.DBus"))
                    {
                        getPropertiesForEnumerate(path, service, interface,
                                                  asyncResp);
                    }
                }
            }
        }
    }
}

struct InProgressEnumerateData
{
    InProgressEnumerateData(const std::string &objectPath,
                            std::shared_ptr<bmcweb::AsyncResp> asyncResp) :
        objectPath(objectPath),
        asyncResp(asyncResp)
    {
    }

    ~InProgressEnumerateData()
    {
        findRemainingObjectsForEnumerate(objectPath, subtree, asyncResp);
    }

    const std::string objectPath;
    std::shared_ptr<GetSubTreeType> subtree;
    std::shared_ptr<bmcweb::AsyncResp> asyncResp;
};

void getManagedObjectsForEnumerate(
    const std::string &object_name, const std::string &object_manager_path,
    const std::string &connection_name,
    std::shared_ptr<InProgressEnumerateData> transaction)
{
    BMCWEB_LOG_DEBUG << "getManagedObjectsForEnumerate " << object_name
                     << " object_manager_path " << object_manager_path
                     << " connection_name " << connection_name;
    crow::connections::systemBus->async_method_call(
        [transaction, object_name,
         connection_name](const boost::system::error_code ec,
                          const dbus::utility::ManagedObjectType &objects) {
            if (ec)
            {
                BMCWEB_LOG_ERROR << "GetManagedObjects on path " << object_name
                                 << " on connection " << connection_name
                                 << " failed with code " << ec;
                return;
            }

            nlohmann::json &dataJson =
                transaction->asyncResp->res.jsonValue["data"];

            for (const auto &objectPath : objects)
            {
                if (boost::starts_with(objectPath.first.str, object_name))
                {
                    BMCWEB_LOG_DEBUG << "Reading object "
                                     << objectPath.first.str;
                    nlohmann::json &objectJson = dataJson[objectPath.first.str];
                    if (objectJson.is_null())
                    {
                        objectJson = nlohmann::json::object();
                    }
                    for (const auto &interface : objectPath.second)
                    {
                        for (const auto &property : interface.second)
                        {
                            nlohmann::json &propertyJson =
                                objectJson[property.first];
                            std::visit([&propertyJson](
                                           auto &&val) { propertyJson = val; },
                                       property.second);
                        }
                    }
                }
                for (const auto &interface : objectPath.second)
                {
                    if (interface.first == "org.freedesktop.DBus.ObjectManager")
                    {
                        getManagedObjectsForEnumerate(
                            objectPath.first.str, objectPath.first.str,
                            connection_name, transaction);
                    }
                }
            }
        },
        connection_name, object_manager_path,
        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
}

void findObjectManagerPathForEnumerate(
    const std::string &object_name, const std::string &connection_name,
    std::shared_ptr<InProgressEnumerateData> transaction)
{
    BMCWEB_LOG_DEBUG << "Finding objectmanager for path " << object_name
                     << " on connection:" << connection_name;
    crow::connections::systemBus->async_method_call(
        [transaction, object_name, connection_name](
            const boost::system::error_code ec,
            const boost::container::flat_map<
                std::string, boost::container::flat_map<
                                 std::string, std::vector<std::string>>>
                &objects) {
            if (ec)
            {
                BMCWEB_LOG_ERROR << "GetAncestors on path " << object_name
                                 << " failed with code " << ec;
                return;
            }

            for (const auto &pathGroup : objects)
            {
                for (const auto &connectionGroup : pathGroup.second)
                {
                    if (connectionGroup.first == connection_name)
                    {
                        // Found the object manager path for this resource.
                        getManagedObjectsForEnumerate(
                            object_name, pathGroup.first, connection_name,
                            transaction);
                        return;
                    }
                }
            }
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetAncestors", object_name,
        std::array<const char *, 1>{"org.freedesktop.DBus.ObjectManager"});
}

// Uses GetObject to add the object info about the target /enumerate path to
// the results of GetSubTree, as GetSubTree will not return info for the
// target path, and then continues on enumerating the rest of the tree.
void getObjectAndEnumerate(std::shared_ptr<InProgressEnumerateData> transaction)
{
    using GetObjectType =
        std::vector<std::pair<std::string, std::vector<std::string>>>;

    crow::connections::systemBus->async_method_call(
        [transaction](const boost::system::error_code ec,
                      const GetObjectType &objects) {
            if (ec)
            {
                BMCWEB_LOG_ERROR << "GetObject for path "
                                 << transaction->objectPath
                                 << " failed with code " << ec;
                return;
            }

            BMCWEB_LOG_DEBUG << "GetObject for " << transaction->objectPath
                             << " has " << objects.size() << " entries";
            if (!objects.empty())
            {
                transaction->subtree->emplace_back(transaction->objectPath,
                                                   objects);
            }

            // Map indicating connection name, and the path where the object
            // manager exists
            boost::container::flat_map<std::string, std::string> connections;

            for (const auto &object : *(transaction->subtree))
            {
                for (const auto &connection : object.second)
                {
                    std::string &objectManagerPath =
                        connections[connection.first];
                    for (const auto &interface : connection.second)
                    {
                        BMCWEB_LOG_DEBUG << connection.first
                                         << " has interface " << interface;
                        if (interface == "org.freedesktop.DBus.ObjectManager")
                        {
                            BMCWEB_LOG_DEBUG << "found object manager path "
                                             << object.first;
                            objectManagerPath = object.first;
                        }
                    }
                }
            }
            BMCWEB_LOG_DEBUG << "Got " << connections.size() << " connections";

            for (const auto &connection : connections)
            {
                // If we already know where the object manager is, we don't
                // need to search for it, we can call directly in to
                // getManagedObjects
                if (!connection.second.empty())
                {
                    getManagedObjectsForEnumerate(
                        transaction->objectPath, connection.second,
                        connection.first, transaction);
                }
                else
                {
                    // otherwise we need to find the object manager path
                    // before we can continue
                    findObjectManagerPathForEnumerate(
                        transaction->objectPath, connection.first, transaction);
                }
            }
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetObject",
        transaction->objectPath, std::array<const char *, 0>());
}

// Structure for storing data on an in progress action
struct InProgressActionData
{
    InProgressActionData(crow::Response &res) : res(res){};
    ~InProgressActionData()
    {
        // Methods could have been called across different owners
        // and interfaces, where some calls failed and some passed.
        //
        // The rules for this are:
        // * if no method was called - error
        // * if a method failed and none passed - error
        //   (converse: if at least one method passed - OK)
        // * for the method output:
        //   * if output processing didn't fail, return the data

        // Only deal with method returns if nothing failed earlier
        if (res.result() == boost::beast::http::status::ok)
        {
            if (!methodPassed)
            {
                if (!methodFailed)
                {
                    setErrorResponse(res, boost::beast::http::status::not_found,
                                     methodNotFoundDesc, notFoundMsg);
                }
            }
            else
            {
                if (outputFailed)
                {
                    setErrorResponse(
                        res, boost::beast::http::status::internal_server_error,
                        "Method output failure", methodOutputFailedMsg);
                }
                else
                {
                    res.jsonValue = {{"status", "ok"},
                                     {"message", "200 OK"},
                                     {"data", methodResponse}};
                }
            }
        }

        res.end();
    }

    void setErrorStatus(const std::string &desc)
    {
        setErrorResponse(res, boost::beast::http::status::bad_request, desc,
                         badReqMsg);
    }
    crow::Response &res;
    std::string path;
    std::string methodName;
    std::string interfaceName;
    bool methodPassed = false;
    bool methodFailed = false;
    bool outputFailed = false;
    bool convertedToArray = false;
    nlohmann::json methodResponse;
    nlohmann::json arguments;
};

std::vector<std::string> dbusArgSplit(const std::string &string)
{
    std::vector<std::string> ret;
    if (string.empty())
    {
        return ret;
    }
    ret.push_back("");
    int containerDepth = 0;

    for (std::string::const_iterator character = string.begin();
         character != string.end(); character++)
    {
        ret.back() += *character;
        switch (*character)
        {
            case ('a'):
                break;
            case ('('):
            case ('{'):
                containerDepth++;
                break;
            case ('}'):
            case (')'):
                containerDepth--;
                if (containerDepth == 0)
                {
                    if (character + 1 != string.end())
                    {
                        ret.push_back("");
                    }
                }
                break;
            default:
                if (containerDepth == 0)
                {
                    if (character + 1 != string.end())
                    {
                        ret.push_back("");
                    }
                }
                break;
        }
    }

    return ret;
}

int convertJsonToDbus(sd_bus_message *m, const std::string &arg_type,
                      const nlohmann::json &input_json)
{
    int r = 0;
    BMCWEB_LOG_DEBUG << "Converting " << input_json.dump()
                     << " to type: " << arg_type;
    const std::vector<std::string> argTypes = dbusArgSplit(arg_type);

    // Assume a single object for now.
    const nlohmann::json *j = &input_json;
    nlohmann::json::const_iterator jIt = input_json.begin();

    for (const std::string &argCode : argTypes)
    {
        // If we are decoding multiple objects, grab the pointer to the
        // iterator, and increment it for the next loop
        if (argTypes.size() > 1)
        {
            if (jIt == input_json.end())
            {
                return -2;
            }
            j = &*jIt;
            jIt++;
        }
        const int64_t *intValue = j->get_ptr<const int64_t *>();
        const uint64_t *uintValue = j->get_ptr<const uint64_t *>();
        const std::string *stringValue = j->get_ptr<const std::string *>();
        const double *doubleValue = j->get_ptr<const double *>();
        const bool *b = j->get_ptr<const bool *>();
        int64_t v = 0;
        double d = 0.0;

        // Do some basic type conversions that make sense.  uint can be
        // converted to int.  int and uint can be converted to double
        if (uintValue != nullptr && intValue == nullptr)
        {
            v = static_cast<int64_t>(*uintValue);
            intValue = &v;
        }
        if (uintValue != nullptr && doubleValue == nullptr)
        {
            d = static_cast<double>(*uintValue);
            doubleValue = &d;
        }
        if (intValue != nullptr && doubleValue == nullptr)
        {
            d = static_cast<double>(*intValue);
            doubleValue = &d;
        }

        if (argCode == "s")
        {
            if (stringValue == nullptr)
            {
                return -1;
            }
            r = sd_bus_message_append_basic(m, argCode[0],
                                            (void *)stringValue->c_str());
            if (r < 0)
            {
                return r;
            }
        }
        else if (argCode == "i")
        {
            if (intValue == nullptr)
            {
                return -1;
            }
            int32_t i = static_cast<int32_t>(*intValue);
            r = sd_bus_message_append_basic(m, argCode[0], &i);
            if (r < 0)
            {
                return r;
            }
        }
        else if (argCode == "b")
        {
            // lots of ways bool could be represented here.  Try them all
            int boolInt = false;
            if (intValue != nullptr)
            {
                boolInt = *intValue > 0 ? 1 : 0;
            }
            else if (b != nullptr)
            {
                boolInt = *b ? 1 : 0;
            }
            else if (stringValue != nullptr)
            {
                boolInt = boost::istarts_with(*stringValue, "t") ? 1 : 0;
            }
            else
            {
                return -1;
            }
            r = sd_bus_message_append_basic(m, argCode[0], &boolInt);
            if (r < 0)
            {
                return r;
            }
        }
        else if (argCode == "n")
        {
            if (intValue == nullptr)
            {
                return -1;
            }
            int16_t n = static_cast<int16_t>(*intValue);
            r = sd_bus_message_append_basic(m, argCode[0], &n);
            if (r < 0)
            {
                return r;
            }
        }
        else if (argCode == "x")
        {
            if (intValue == nullptr)
            {
                return -1;
            }
            r = sd_bus_message_append_basic(m, argCode[0], intValue);
            if (r < 0)
            {
                return r;
            }
        }
        else if (argCode == "y")
        {
            if (uintValue == nullptr)
            {
                return -1;
            }
            uint8_t y = static_cast<uint8_t>(*uintValue);
            r = sd_bus_message_append_basic(m, argCode[0], &y);
        }
        else if (argCode == "q")
        {
            if (uintValue == nullptr)
            {
                return -1;
            }
            uint16_t q = static_cast<uint16_t>(*uintValue);
            r = sd_bus_message_append_basic(m, argCode[0], &q);
        }
        else if (argCode == "u")
        {
            if (uintValue == nullptr)
            {
                return -1;
            }
            uint32_t u = static_cast<uint32_t>(*uintValue);
            r = sd_bus_message_append_basic(m, argCode[0], &u);
        }
        else if (argCode == "t")
        {
            if (uintValue == nullptr)
            {
                return -1;
            }
            r = sd_bus_message_append_basic(m, argCode[0], uintValue);
        }
        else if (argCode == "d")
        {
            sd_bus_message_append_basic(m, argCode[0], doubleValue);
        }
        else if (boost::starts_with(argCode, "a"))
        {
            std::string containedType = argCode.substr(1);
            r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY,
                                              containedType.c_str());
            if (r < 0)
            {
                return r;
            }

            for (nlohmann::json::const_iterator it = j->begin(); it != j->end();
                 ++it)
            {
                r = convertJsonToDbus(m, containedType, *it);
                if (r < 0)
                {
                    return r;
                }
            }
            sd_bus_message_close_container(m);
        }
        else if (boost::starts_with(argCode, "v"))
        {
            std::string containedType = argCode.substr(1);
            BMCWEB_LOG_DEBUG << "variant type: " << argCode
                             << " appending variant of type: " << containedType;
            r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT,
                                              containedType.c_str());
            if (r < 0)
            {
                return r;
            }

            r = convertJsonToDbus(m, containedType, input_json);
            if (r < 0)
            {
                return r;
            }

            r = sd_bus_message_close_container(m);
            if (r < 0)
            {
                return r;
            }
        }
        else if (boost::starts_with(argCode, "(") &&
                 boost::ends_with(argCode, ")"))
        {
            std::string containedType = argCode.substr(1, argCode.size() - 1);
            r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT,
                                              containedType.c_str());
            if (r < 0)
            {
                return r;
            }

            nlohmann::json::const_iterator it = j->begin();
            for (const std::string &argCode : dbusArgSplit(arg_type))
            {
                if (it == j->end())
                {
                    return -1;
                }
                r = convertJsonToDbus(m, argCode, *it);
                if (r < 0)
                {
                    return r;
                }
                it++;
            }
            r = sd_bus_message_close_container(m);
        }
        else if (boost::starts_with(argCode, "{") &&
                 boost::ends_with(argCode, "}"))
        {
            std::string containedType = argCode.substr(1, argCode.size() - 1);
            r = sd_bus_message_open_container(m, SD_BUS_TYPE_DICT_ENTRY,
                                              containedType.c_str());
            if (r < 0)
            {
                return r;
            }

            std::vector<std::string> codes = dbusArgSplit(containedType);
            if (codes.size() != 2)
            {
                return -1;
            }
            const std::string &key_type = codes[0];
            const std::string &value_type = codes[1];
            for (auto it : j->items())
            {
                r = convertJsonToDbus(m, key_type, it.key());
                if (r < 0)
                {
                    return r;
                }

                r = convertJsonToDbus(m, value_type, it.value());
                if (r < 0)
                {
                    return r;
                }
            }
            r = sd_bus_message_close_container(m);
        }
        else
        {
            return -2;
        }
        if (r < 0)
        {
            return r;
        }

        if (argTypes.size() > 1)
        {
            jIt++;
        }
    }

    return r;
}

template <typename T>
int readMessageItem(const std::string &typeCode, sdbusplus::message::message &m,
                    nlohmann::json &data)
{
    T value;

    int r = sd_bus_message_read_basic(m.get(), typeCode.front(), &value);
    if (r < 0)
    {
        BMCWEB_LOG_ERROR << "sd_bus_message_read_basic on type " << typeCode
                         << " failed!";
        return r;
    }

    data = value;
    return 0;
}

int convertDBusToJSON(const std::string &returnType,
                      sdbusplus::message::message &m, nlohmann::json &response);

int readDictEntryFromMessage(const std::string &typeCode,
                             sdbusplus::message::message &m,
                             nlohmann::json &object)
{
    std::vector<std::string> types = dbusArgSplit(typeCode);
    if (types.size() != 2)
    {
        BMCWEB_LOG_ERROR << "wrong number contained types in dictionary: "
                         << types.size();
        return -1;
    }

    int r = sd_bus_message_enter_container(m.get(), SD_BUS_TYPE_DICT_ENTRY,
                                           typeCode.c_str());
    if (r < 0)
    {
        BMCWEB_LOG_ERROR << "sd_bus_message_enter_container with rc " << r;
        return r;
    }

    nlohmann::json key;
    r = convertDBusToJSON(types[0], m, key);
    if (r < 0)
    {
        return r;
    }

    const std::string *keyPtr = key.get_ptr<const std::string *>();
    if (keyPtr == nullptr)
    {
        // json doesn't support non-string keys.  If we hit this condition,
        // convert the result to a string so we can proceed
        key = key.dump();
        keyPtr = key.get_ptr<const std::string *>();
        // in theory this can't fail now, but lets be paranoid about it
        // anyway
        if (keyPtr == nullptr)
        {
            return -1;
        }
    }
    nlohmann::json &value = object[*keyPtr];

    r = convertDBusToJSON(types[1], m, value);
    if (r < 0)
    {
        return r;
    }

    r = sd_bus_message_exit_container(m.get());
    if (r < 0)
    {
        BMCWEB_LOG_ERROR << "sd_bus_message_exit_container failed";
        return r;
    }

    return 0;
}

int readArrayFromMessage(const std::string &typeCode,
                         sdbusplus::message::message &m, nlohmann::json &data)
{
    if (typeCode.size() < 2)
    {
        BMCWEB_LOG_ERROR << "Type code " << typeCode
                         << " too small for an array";
        return -1;
    }

    std::string containedType = typeCode.substr(1);

    int r = sd_bus_message_enter_container(m.get(), SD_BUS_TYPE_ARRAY,
                                           containedType.c_str());
    if (r < 0)
    {
        BMCWEB_LOG_ERROR << "sd_bus_message_enter_container failed with rc "
                         << r;
        return r;
    }

    bool dict = boost::starts_with(containedType, "{") &&
                boost::ends_with(containedType, "}");

    if (dict)
    {
        // Remove the { }
        containedType = containedType.substr(1, containedType.size() - 2);
        data = nlohmann::json::object();
    }
    else
    {
        data = nlohmann::json::array();
    }

    while (true)
    {
        r = sd_bus_message_at_end(m.get(), false);
        if (r < 0)
        {
            BMCWEB_LOG_ERROR << "sd_bus_message_at_end failed";
            return r;
        }

        if (r > 0)
        {
            break;
        }

        // Dictionaries are only ever seen in an array
        if (dict)
        {
            r = readDictEntryFromMessage(containedType, m, data);
            if (r < 0)
            {
                return r;
            }
        }
        else
        {
            data.push_back(nlohmann::json());

            r = convertDBusToJSON(containedType, m, data.back());
            if (r < 0)
            {
                return r;
            }
        }
    }

    r = sd_bus_message_exit_container(m.get());
    if (r < 0)
    {
        BMCWEB_LOG_ERROR << "sd_bus_message_exit_container failed";
        return r;
    }

    return 0;
}

int readStructFromMessage(const std::string &typeCode,
                          sdbusplus::message::message &m, nlohmann::json &data)
{
    if (typeCode.size() < 3)
    {
        BMCWEB_LOG_ERROR << "Type code " << typeCode
                         << " too small for a struct";
        return -1;
    }

    std::string containedTypes = typeCode.substr(1, typeCode.size() - 2);
    std::vector<std::string> types = dbusArgSplit(containedTypes);

    int r = sd_bus_message_enter_container(m.get(), SD_BUS_TYPE_STRUCT,
                                           containedTypes.c_str());
    if (r < 0)
    {
        BMCWEB_LOG_ERROR << "sd_bus_message_enter_container failed with rc "
                         << r;
        return r;
    }

    for (const std::string &type : types)
    {
        data.push_back(nlohmann::json());
        r = convertDBusToJSON(type, m, data.back());
        if (r < 0)
        {
            return r;
        }
    }

    r = sd_bus_message_exit_container(m.get());
    if (r < 0)
    {
        BMCWEB_LOG_ERROR << "sd_bus_message_exit_container failed";
        return r;
    }
    return 0;
}

int readVariantFromMessage(sdbusplus::message::message &m, nlohmann::json &data)
{
    const char *containerType;
    int r = sd_bus_message_peek_type(m.get(), NULL, &containerType);
    if (r < 0)
    {
        BMCWEB_LOG_ERROR << "sd_bus_message_peek_type failed";
        return r;
    }

    r = sd_bus_message_enter_container(m.get(), SD_BUS_TYPE_VARIANT,
                                       containerType);
    if (r < 0)
    {
        BMCWEB_LOG_ERROR << "sd_bus_message_enter_container failed with rc "
                         << r;
        return r;
    }

    r = convertDBusToJSON(containerType, m, data);
    if (r < 0)
    {
        return r;
    }

    r = sd_bus_message_exit_container(m.get());
    if (r < 0)
    {
        BMCWEB_LOG_ERROR << "sd_bus_message_enter_container failed";
        return r;
    }

    return 0;
}

int convertDBusToJSON(const std::string &returnType,
                      sdbusplus::message::message &m, nlohmann::json &response)
{
    int r = 0;
    const std::vector<std::string> returnTypes = dbusArgSplit(returnType);

    for (const std::string &typeCode : returnTypes)
    {
        nlohmann::json *thisElement = &response;
        if (returnTypes.size() > 1)
        {
            response.push_back(nlohmann::json{});
            thisElement = &response.back();
        }

        if (typeCode == "s")
        {
            r = readMessageItem<char *>(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (typeCode == "g")
        {
            r = readMessageItem<char *>(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (typeCode == "o")
        {
            r = readMessageItem<char *>(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (typeCode == "b")
        {
            r = readMessageItem<int>(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }

            *thisElement = static_cast<bool>(thisElement->get<int>());
        }
        else if (typeCode == "u")
        {
            r = readMessageItem<uint32_t>(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (typeCode == "i")
        {
            r = readMessageItem<int32_t>(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (typeCode == "x")
        {
            r = readMessageItem<int64_t>(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (typeCode == "t")
        {
            r = readMessageItem<uint64_t>(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (typeCode == "n")
        {
            r = readMessageItem<int16_t>(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (typeCode == "q")
        {
            r = readMessageItem<uint16_t>(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (typeCode == "y")
        {
            r = readMessageItem<uint8_t>(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (typeCode == "d")
        {
            r = readMessageItem<double>(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (typeCode == "h")
        {
            r = readMessageItem<int>(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (boost::starts_with(typeCode, "a"))
        {
            r = readArrayFromMessage(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (boost::starts_with(typeCode, "(") &&
                 boost::ends_with(typeCode, ")"))
        {
            r = readStructFromMessage(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (boost::starts_with(typeCode, "v"))
        {
            r = readVariantFromMessage(m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else
        {
            BMCWEB_LOG_ERROR << "Invalid D-Bus signature type " << typeCode;
            return -2;
        }
    }

    return 0;
}

void handleMethodResponse(std::shared_ptr<InProgressActionData> transaction,
                          sdbusplus::message::message &m,
                          const std::string &returnType)
{
    nlohmann::json data;

    int r = convertDBusToJSON(returnType, m, data);
    if (r < 0)
    {
        transaction->outputFailed = true;
        return;
    }

    if (data.is_null())
    {
        return;
    }

    if (transaction->methodResponse.is_null())
    {
        transaction->methodResponse = std::move(data);
        return;
    }

    // If they're both dictionaries or arrays, merge into one.
    // Otherwise, make the results an array with every result
    // an entry.  Could also just fail in that case, but it
    // seems better to get the data back somehow.

    if (transaction->methodResponse.is_object() && data.is_object())
    {
        for (const auto &obj : data.items())
        {
            // Note: Will overwrite the data for a duplicate key
            transaction->methodResponse.emplace(obj.key(),
                                                std::move(obj.value()));
        }
        return;
    }

    if (transaction->methodResponse.is_array() && data.is_array())
    {
        for (auto &obj : data)
        {
            transaction->methodResponse.push_back(std::move(obj));
        }
        return;
    }

    if (!transaction->convertedToArray)
    {
        // They are different types. May as well turn them into an array
        nlohmann::json j = std::move(transaction->methodResponse);
        transaction->methodResponse = nlohmann::json::array();
        transaction->methodResponse.push_back(std::move(j));
        transaction->methodResponse.push_back(std::move(data));
        transaction->convertedToArray = true;
    }
    else
    {
        transaction->methodResponse.push_back(std::move(data));
    }
}

void findActionOnInterface(std::shared_ptr<InProgressActionData> transaction,
                           const std::string &connectionName)
{
    BMCWEB_LOG_DEBUG << "findActionOnInterface for connection "
                     << connectionName;
    crow::connections::systemBus->async_method_call(
        [transaction, connectionName{std::string(connectionName)}](
            const boost::system::error_code ec,
            const std::string &introspect_xml) {
            BMCWEB_LOG_DEBUG << "got xml:\n " << introspect_xml;
            if (ec)
            {
                BMCWEB_LOG_ERROR
                    << "Introspect call failed with error: " << ec.message()
                    << " on process: " << connectionName << "\n";
                return;
            }
            tinyxml2::XMLDocument doc;

            doc.Parse(introspect_xml.data(), introspect_xml.size());
            tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
            if (pRoot == nullptr)
            {
                BMCWEB_LOG_ERROR << "XML document failed to parse "
                                 << connectionName << "\n";
                return;
            }
            tinyxml2::XMLElement *interfaceNode =
                pRoot->FirstChildElement("interface");
            while (interfaceNode != nullptr)
            {
                const char *thisInterfaceName =
                    interfaceNode->Attribute("name");
                if (thisInterfaceName != nullptr)
                {
                    if (!transaction->interfaceName.empty() &&
                        (transaction->interfaceName != thisInterfaceName))
                    {
                        interfaceNode =
                            interfaceNode->NextSiblingElement("interface");
                        continue;
                    }

                    tinyxml2::XMLElement *methodNode =
                        interfaceNode->FirstChildElement("method");
                    while (methodNode != nullptr)
                    {
                        const char *thisMethodName =
                            methodNode->Attribute("name");
                        BMCWEB_LOG_DEBUG << "Found method: " << thisMethodName;
                        if (thisMethodName != nullptr &&
                            thisMethodName == transaction->methodName)
                        {
                            BMCWEB_LOG_DEBUG
                                << "Found method named " << thisMethodName
                                << " on interface " << thisInterfaceName;
                            sdbusplus::message::message m =
                                crow::connections::systemBus->new_method_call(
                                    connectionName.c_str(),
                                    transaction->path.c_str(),
                                    thisInterfaceName,
                                    transaction->methodName.c_str());

                            tinyxml2::XMLElement *argumentNode =
                                methodNode->FirstChildElement("arg");

                            std::string returnType;

                            // Find the output type
                            while (argumentNode != nullptr)
                            {
                                const char *argDirection =
                                    argumentNode->Attribute("direction");
                                const char *argType =
                                    argumentNode->Attribute("type");
                                if (argDirection != nullptr &&
                                    argType != nullptr &&
                                    std::string(argDirection) == "out")
                                {
                                    returnType = argType;
                                    break;
                                }
                                argumentNode =
                                    argumentNode->NextSiblingElement("arg");
                            }

                            nlohmann::json::const_iterator argIt =
                                transaction->arguments.begin();

                            argumentNode = methodNode->FirstChildElement("arg");

                            while (argumentNode != nullptr)
                            {
                                const char *argDirection =
                                    argumentNode->Attribute("direction");
                                const char *argType =
                                    argumentNode->Attribute("type");
                                if (argDirection != nullptr &&
                                    argType != nullptr &&
                                    std::string(argDirection) == "in")
                                {
                                    if (argIt == transaction->arguments.end())
                                    {
                                        transaction->setErrorStatus(
                                            "Invalid method args");
                                        return;
                                    }
                                    if (convertJsonToDbus(m.get(),
                                                          std::string(argType),
                                                          *argIt) < 0)
                                    {
                                        transaction->setErrorStatus(
                                            "Invalid method arg type");
                                        return;
                                    }

                                    argIt++;
                                }
                                argumentNode =
                                    argumentNode->NextSiblingElement("arg");
                            }

                            crow::connections::systemBus->async_send(
                                m, [transaction, returnType](
                                       boost::system::error_code ec,
                                       sdbusplus::message::message &m) {
                                    if (ec)
                                    {
                                        transaction->methodFailed = true;
                                        const sd_bus_error *e = m.get_error();

                                        if (e)
                                        {
                                            setErrorResponse(
                                                transaction->res,
                                                boost::beast::http::status::
                                                    bad_request,
                                                e->name, e->message);
                                        }
                                        else
                                        {
                                            setErrorResponse(
                                                transaction->res,
                                                boost::beast::http::status::
                                                    bad_request,
                                                "Method call failed",
                                                methodFailedMsg);
                                        }
                                        return;
                                    }
                                    else
                                    {
                                        transaction->methodPassed = true;
                                    }

                                    handleMethodResponse(transaction, m,
                                                         returnType);
                                });
                            break;
                        }
                        methodNode = methodNode->NextSiblingElement("method");
                    }
                }
                interfaceNode = interfaceNode->NextSiblingElement("interface");
            }
        },
        connectionName, transaction->path,
        "org.freedesktop.DBus.Introspectable", "Introspect");
}

void handleAction(const crow::Request &req, crow::Response &res,
                  const std::string &objectPath, const std::string &methodName)
{
    BMCWEB_LOG_DEBUG << "handleAction on path: " << objectPath << " and method "
                     << methodName;
    nlohmann::json requestDbusData =
        nlohmann::json::parse(req.body, nullptr, false);

    if (requestDbusData.is_discarded())
    {
        setErrorResponse(res, boost::beast::http::status::bad_request,
                         noJsonDesc, badReqMsg);
        res.end();
        return;
    }
    nlohmann::json::iterator data = requestDbusData.find("data");
    if (data == requestDbusData.end())
    {
        setErrorResponse(res, boost::beast::http::status::bad_request,
                         noJsonDesc, badReqMsg);
        res.end();
        return;
    }

    if (!data->is_array())
    {
        setErrorResponse(res, boost::beast::http::status::bad_request,
                         noJsonDesc, badReqMsg);
        res.end();
        return;
    }
    auto transaction = std::make_shared<InProgressActionData>(res);

    transaction->path = objectPath;
    transaction->methodName = methodName;
    transaction->arguments = std::move(*data);
    crow::connections::systemBus->async_method_call(
        [transaction](
            const boost::system::error_code ec,
            const std::vector<std::pair<std::string, std::vector<std::string>>>
                &interfaceNames) {
            if (ec || interfaceNames.size() <= 0)
            {
                BMCWEB_LOG_ERROR << "Can't find object";
                setErrorResponse(transaction->res,
                                 boost::beast::http::status::not_found,
                                 notFoundDesc, notFoundMsg);
                return;
            }

            BMCWEB_LOG_DEBUG << "GetObject returned " << interfaceNames.size()
                             << " object(s)";

            for (const std::pair<std::string, std::vector<std::string>>
                     &object : interfaceNames)
            {
                findActionOnInterface(transaction, object.first);
            }
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetObject", objectPath,
        std::array<std::string, 0>());
}

void handleDelete(const crow::Request &req, crow::Response &res,
                  const std::string &objectPath)
{
    BMCWEB_LOG_DEBUG << "handleDelete on path: " << objectPath;

    crow::connections::systemBus->async_method_call(
        [&res, objectPath](
            const boost::system::error_code ec,
            const std::vector<std::pair<std::string, std::vector<std::string>>>
                &interfaceNames) {
            if (ec || interfaceNames.size() <= 0)
            {
                BMCWEB_LOG_ERROR << "Can't find object";
                setErrorResponse(res,
                                 boost::beast::http::status::method_not_allowed,
                                 methodNotAllowedDesc, methodNotAllowedMsg);
                res.end();
                return;
            }

            auto transaction = std::make_shared<InProgressActionData>(res);
            transaction->path = objectPath;
            transaction->methodName = "Delete";
            transaction->interfaceName = "xyz.openbmc_project.Object.Delete";

            for (const std::pair<std::string, std::vector<std::string>>
                     &object : interfaceNames)
            {
                findActionOnInterface(transaction, object.first);
            }
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetObject", objectPath,
        std::array<const char *, 0>());
}

void handleList(crow::Response &res, const std::string &objectPath,
                int32_t depth = 0)
{
    crow::connections::systemBus->async_method_call(
        [&res](const boost::system::error_code ec,
               std::vector<std::string> &objectPaths) {
            if (ec)
            {
                setErrorResponse(res, boost::beast::http::status::not_found,
                                 notFoundDesc, notFoundMsg);
            }
            else
            {
                res.jsonValue = {{"status", "ok"},
                                 {"message", "200 OK"},
                                 {"data", std::move(objectPaths)}};
            }
            res.end();
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", objectPath,
        depth, std::array<std::string, 0>());
}

void handleEnumerate(crow::Response &res, const std::string &objectPath)
{
    BMCWEB_LOG_DEBUG << "Doing enumerate on " << objectPath;
    auto asyncResp = std::make_shared<bmcweb::AsyncResp>(res);

    asyncResp->res.jsonValue = {{"message", "200 OK"},
                                {"status", "ok"},
                                {"data", nlohmann::json::object()}};

    crow::connections::systemBus->async_method_call(
        [objectPath, asyncResp](const boost::system::error_code ec,
                                GetSubTreeType &object_names) {
            auto transaction = std::make_shared<InProgressEnumerateData>(
                objectPath, asyncResp);

            transaction->subtree =
                std::make_shared<GetSubTreeType>(std::move(object_names));

            if (ec)
            {
                BMCWEB_LOG_ERROR << "GetSubTree failed on "
                                 << transaction->objectPath;
                setErrorResponse(transaction->asyncResp->res,
                                 boost::beast::http::status::not_found,
                                 notFoundDesc, notFoundMsg);
                return;
            }

            // Add the data for the path passed in to the results
            // as if GetSubTree returned it, and continue on enumerating
            getObjectAndEnumerate(transaction);
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetSubTree", objectPath,
        static_cast<int32_t>(0), std::array<const char *, 0>());
}

void handleGet(crow::Response &res, std::string &objectPath,
               std::string &destProperty)
{
    BMCWEB_LOG_DEBUG << "handleGet: " << objectPath << " prop:" << destProperty;
    std::shared_ptr<std::string> propertyName =
        std::make_shared<std::string>(std::move(destProperty));

    std::shared_ptr<std::string> path =
        std::make_shared<std::string>(std::move(objectPath));

    using GetObjectType =
        std::vector<std::pair<std::string, std::vector<std::string>>>;
    crow::connections::systemBus->async_method_call(
        [&res, path, propertyName](const boost::system::error_code ec,
                                   const GetObjectType &object_names) {
            if (ec || object_names.size() <= 0)
            {
                setErrorResponse(res, boost::beast::http::status::not_found,
                                 notFoundDesc, notFoundMsg);
                res.end();
                return;
            }
            std::shared_ptr<nlohmann::json> response =
                std::make_shared<nlohmann::json>(nlohmann::json::object());
            // The mapper should never give us an empty interface names
            // list, but check anyway
            for (const std::pair<std::string, std::vector<std::string>>
                     connection : object_names)
            {
                const std::vector<std::string> &interfaceNames =
                    connection.second;

                if (interfaceNames.size() <= 0)
                {
                    setErrorResponse(res, boost::beast::http::status::not_found,
                                     notFoundDesc, notFoundMsg);
                    res.end();
                    return;
                }

                for (const std::string &interface : interfaceNames)
                {
                    sdbusplus::message::message m =
                        crow::connections::systemBus->new_method_call(
                            connection.first.c_str(), path->c_str(),
                            "org.freedesktop.DBus.Properties", "GetAll");
                    m.append(interface);
                    crow::connections::systemBus->async_send(
                        m, [&res, response,
                            propertyName](const boost::system::error_code ec,
                                          sdbusplus::message::message &msg) {
                            if (ec)
                            {
                                BMCWEB_LOG_ERROR << "Bad dbus request error: "
                                                 << ec;
                            }
                            else
                            {
                                nlohmann::json properties;
                                int r =
                                    convertDBusToJSON("a{sv}", msg, properties);
                                if (r < 0)
                                {
                                    BMCWEB_LOG_ERROR
                                        << "convertDBusToJSON failed";
                                }
                                else
                                {
                                    for (auto &prop : properties.items())
                                    {
                                        // if property name is empty, or
                                        // matches our search query, add it
                                        // to the response json

                                        if (propertyName->empty())
                                        {
                                            (*response)[prop.key()] =
                                                std::move(prop.value());
                                        }
                                        else if (prop.key() == *propertyName)
                                        {
                                            *response = std::move(prop.value());
                                        }
                                    }
                                }
                            }
                            if (response.use_count() == 1)
                            {
                                if (!propertyName->empty() && response->empty())
                                {
                                    setErrorResponse(
                                        res,
                                        boost::beast::http::status::not_found,
                                        propNotFoundDesc, notFoundMsg);
                                }
                                else
                                {
                                    res.jsonValue = {{"status", "ok"},
                                                     {"message", "200 OK"},
                                                     {"data", *response}};
                                }
                                res.end();
                            }
                        });
                }
            }
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetObject", *path,
        std::array<std::string, 0>());
}

struct AsyncPutRequest
{
    AsyncPutRequest(crow::Response &res) : res(res)
    {
    }
    ~AsyncPutRequest()
    {
        if (res.jsonValue.empty())
        {
            setErrorResponse(res, boost::beast::http::status::forbidden,
                             forbiddenMsg, forbiddenPropDesc);
        }

        res.end();
    }

    void setErrorStatus(const std::string &desc)
    {
        setErrorResponse(res, boost::beast::http::status::internal_server_error,
                         desc, badReqMsg);
    }

    crow::Response &res;
    std::string objectPath;
    std::string propertyName;
    nlohmann::json propertyValue;
};

void handlePut(const crow::Request &req, crow::Response &res,
               const std::string &objectPath, const std::string &destProperty)
{
    if (destProperty.empty())
    {
        setErrorResponse(res, boost::beast::http::status::forbidden,
                         forbiddenResDesc, forbiddenMsg);
        res.end();
        return;
    }

    nlohmann::json requestDbusData =
        nlohmann::json::parse(req.body, nullptr, false);

    if (requestDbusData.is_discarded())
    {
        setErrorResponse(res, boost::beast::http::status::bad_request,
                         noJsonDesc, badReqMsg);
        res.end();
        return;
    }

    nlohmann::json::const_iterator propertyIt = requestDbusData.find("data");
    if (propertyIt == requestDbusData.end())
    {
        setErrorResponse(res, boost::beast::http::status::bad_request,
                         noJsonDesc, badReqMsg);
        res.end();
        return;
    }
    const nlohmann::json &propertySetValue = *propertyIt;
    auto transaction = std::make_shared<AsyncPutRequest>(res);
    transaction->objectPath = objectPath;
    transaction->propertyName = destProperty;
    transaction->propertyValue = propertySetValue;

    using GetObjectType =
        std::vector<std::pair<std::string, std::vector<std::string>>>;

    crow::connections::systemBus->async_method_call(
        [transaction](const boost::system::error_code ec,
                      const GetObjectType &object_names) {
            if (!ec && object_names.size() <= 0)
            {
                setErrorResponse(transaction->res,
                                 boost::beast::http::status::not_found,
                                 propNotFoundDesc, notFoundMsg);
                return;
            }

            for (const std::pair<std::string, std::vector<std::string>>
                     connection : object_names)
            {
                const std::string &connectionName = connection.first;

                crow::connections::systemBus->async_method_call(
                    [connectionName{std::string(connectionName)},
                     transaction](const boost::system::error_code ec,
                                  const std::string &introspectXml) {
                        if (ec)
                        {
                            BMCWEB_LOG_ERROR
                                << "Introspect call failed with error: "
                                << ec.message()
                                << " on process: " << connectionName;
                            transaction->setErrorStatus("Unexpected Error");
                            return;
                        }
                        tinyxml2::XMLDocument doc;

                        doc.Parse(introspectXml.c_str());
                        tinyxml2::XMLNode *pRoot =
                            doc.FirstChildElement("node");
                        if (pRoot == nullptr)
                        {
                            BMCWEB_LOG_ERROR << "XML document failed to parse: "
                                             << introspectXml;
                            transaction->setErrorStatus("Unexpected Error");
                            return;
                        }
                        tinyxml2::XMLElement *ifaceNode =
                            pRoot->FirstChildElement("interface");
                        while (ifaceNode != nullptr)
                        {
                            const char *interfaceName =
                                ifaceNode->Attribute("name");
                            BMCWEB_LOG_DEBUG << "found interface "
                                             << interfaceName;
                            tinyxml2::XMLElement *propNode =
                                ifaceNode->FirstChildElement("property");
                            while (propNode != nullptr)
                            {
                                const char *propertyName =
                                    propNode->Attribute("name");
                                BMCWEB_LOG_DEBUG << "Found property "
                                                 << propertyName;
                                if (propertyName == transaction->propertyName)
                                {
                                    const char *argType =
                                        propNode->Attribute("type");
                                    if (argType != nullptr)
                                    {
                                        sdbusplus::message::message m =
                                            crow::connections::systemBus
                                                ->new_method_call(
                                                    connectionName.c_str(),
                                                    transaction->objectPath
                                                        .c_str(),
                                                    "org.freedesktop.DBus."
                                                    "Properties",
                                                    "Set");
                                        m.append(interfaceName,
                                                 transaction->propertyName);
                                        int r = sd_bus_message_open_container(
                                            m.get(), SD_BUS_TYPE_VARIANT,
                                            argType);
                                        if (r < 0)
                                        {
                                            transaction->setErrorStatus(
                                                "Unexpected Error");
                                            return;
                                        }
                                        r = convertJsonToDbus(
                                            m.get(), argType,
                                            transaction->propertyValue);
                                        if (r < 0)
                                        {
                                            transaction->setErrorStatus(
                                                "Invalid arg type");
                                            return;
                                        }
                                        r = sd_bus_message_close_container(
                                            m.get());
                                        if (r < 0)
                                        {
                                            transaction->setErrorStatus(
                                                "Unexpected Error");
                                            return;
                                        }
                                        crow::connections::systemBus
                                            ->async_send(
                                                m,
                                                [transaction](
                                                    boost::system::error_code
                                                        ec,
                                                    sdbusplus::message::message
                                                        &m) {
                                                    BMCWEB_LOG_DEBUG << "sent";
                                                    if (ec)
                                                    {
                                                        const sd_bus_error *e =
                                                            m.get_error();
                                                        setErrorResponse(
                                                            transaction->res,
                                                            boost::beast::http::
                                                                status::
                                                                    forbidden,
                                                            (e) ? e->name
                                                                : ec.category()
                                                                      .name(),
                                                            (e) ? e->message
                                                                : ec.message());
                                                    }
                                                    else
                                                    {
                                                        transaction->res
                                                            .jsonValue = {
                                                            {"status", "ok"},
                                                            {"message",
                                                             "200 OK"},
                                                            {"data", nullptr}};
                                                    }
                                                });
                                    }
                                }
                                propNode =
                                    propNode->NextSiblingElement("property");
                            }
                            ifaceNode =
                                ifaceNode->NextSiblingElement("interface");
                        }
                    },
                    connectionName, transaction->objectPath,
                    "org.freedesktop.DBus.Introspectable", "Introspect");
            }
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetObject",
        transaction->objectPath, std::array<std::string, 0>());
}

inline void handleDBusUrl(const crow::Request &req, crow::Response &res,
                          std::string &objectPath)
{

    // If accessing a single attribute, fill in and update objectPath,
    // otherwise leave destProperty blank
    std::string destProperty = "";
    const char *attrSeperator = "/attr/";
    size_t attrPosition = objectPath.find(attrSeperator);
    if (attrPosition != objectPath.npos)
    {
        destProperty = objectPath.substr(attrPosition + strlen(attrSeperator),
                                         objectPath.length());
        objectPath = objectPath.substr(0, attrPosition);
    }

    if (req.method() == "POST"_method)
    {
        constexpr const char *actionSeperator = "/action/";
        size_t actionPosition = objectPath.find(actionSeperator);
        if (actionPosition != objectPath.npos)
        {
            std::string postProperty =
                objectPath.substr((actionPosition + strlen(actionSeperator)),
                                  objectPath.length());
            objectPath = objectPath.substr(0, actionPosition);
            handleAction(req, res, objectPath, postProperty);
            return;
        }
    }
    else if (req.method() == "GET"_method)
    {
        if (boost::ends_with(objectPath, "/enumerate"))
        {
            objectPath.erase(objectPath.end() - sizeof("enumerate"),
                             objectPath.end());
            handleEnumerate(res, objectPath);
        }
        else if (boost::ends_with(objectPath, "/list"))
        {
            objectPath.erase(objectPath.end() - sizeof("list"),
                             objectPath.end());
            handleList(res, objectPath);
        }
        else
        {
            // Trim any trailing "/" at the end
            if (boost::ends_with(objectPath, "/"))
            {
                objectPath.pop_back();
                handleList(res, objectPath, 1);
            }
            else
            {
                handleGet(res, objectPath, destProperty);
            }
        }
        return;
    }
    else if (req.method() == "PUT"_method)
    {
        handlePut(req, res, objectPath, destProperty);
        return;
    }
    else if (req.method() == "DELETE"_method)
    {
        handleDelete(req, res, objectPath);
        return;
    }

    setErrorResponse(res, boost::beast::http::status::method_not_allowed,
                     methodNotAllowedDesc, methodNotAllowedMsg);
    res.end();
}

template <typename... Middlewares> void requestRoutes(Crow<Middlewares...> &app)
{
    BMCWEB_ROUTE(app, "/bus/")
        .requires({"Login"})
        .methods("GET"_method)(
            [](const crow::Request &req, crow::Response &res) {
                res.jsonValue = {{"busses", {{{"name", "system"}}}},
                                 {"status", "ok"}};
                res.end();
            });

    BMCWEB_ROUTE(app, "/bus/system/")
        .requires({"Login"})
        .methods("GET"_method)(
            [](const crow::Request &req, crow::Response &res) {
                auto myCallback = [&res](const boost::system::error_code ec,
                                         std::vector<std::string> &names) {
                    if (ec)
                    {
                        BMCWEB_LOG_ERROR << "Dbus call failed with code " << ec;
                        res.result(
                            boost::beast::http::status::internal_server_error);
                    }
                    else
                    {
                        std::sort(names.begin(), names.end());
                        res.jsonValue = {{"status", "ok"}};
                        auto &objectsSub = res.jsonValue["objects"];
                        for (auto &name : names)
                        {
                            objectsSub.push_back({{"name", name}});
                        }
                    }
                    res.end();
                };
                crow::connections::systemBus->async_method_call(
                    std::move(myCallback), "org.freedesktop.DBus", "/",
                    "org.freedesktop.DBus", "ListNames");
            });

    BMCWEB_ROUTE(app, "/list/")
        .requires({"Login"})
        .methods("GET"_method)(
            [](const crow::Request &req, crow::Response &res) {
                handleList(res, "/");
            });

    BMCWEB_ROUTE(app, "/xyz/<path>")
        .requires({"Login"})
        .methods("GET"_method)([](const crow::Request &req, crow::Response &res,
                                  const std::string &path) {
            std::string objectPath = "/xyz/" + path;
            handleDBusUrl(req, res, objectPath);
        });

    BMCWEB_ROUTE(app, "/xyz/<path>")
        .requires({"ConfigureComponents", "ConfigureManager"})
        .methods("PUT"_method, "POST"_method, "DELETE"_method)(
            [](const crow::Request &req, crow::Response &res,
               const std::string &path) {
                std::string objectPath = "/xyz/" + path;
                handleDBusUrl(req, res, objectPath);
            });

    BMCWEB_ROUTE(app, "/org/<path>")
        .requires({"Login"})
        .methods("GET"_method)([](const crow::Request &req, crow::Response &res,
                                  const std::string &path) {
            std::string objectPath = "/org/" + path;
            handleDBusUrl(req, res, objectPath);
        });

    BMCWEB_ROUTE(app, "/org/<path>")
        .requires({"ConfigureComponents", "ConfigureManager"})
        .methods("PUT"_method, "POST"_method, "DELETE"_method)(
            [](const crow::Request &req, crow::Response &res,
               const std::string &path) {
                std::string objectPath = "/org/" + path;
                handleDBusUrl(req, res, objectPath);
            });

    BMCWEB_ROUTE(app, "/download/dump/<str>/")
        .requires({"ConfigureManager"})
        .methods("GET"_method)([](const crow::Request &req, crow::Response &res,
                                  const std::string &dumpId) {
            std::regex validFilename("^[\\w\\- ]+(\\.?[\\w\\- ]*)$");
            if (!std::regex_match(dumpId, validFilename))
            {
                res.result(boost::beast::http::status::bad_request);
                res.end();
                return;
            }
            std::filesystem::path loc(
                "/var/lib/phosphor-debug-collector/dumps");

            loc /= dumpId;

            if (!std::filesystem::exists(loc) ||
                !std::filesystem::is_directory(loc))
            {
                BMCWEB_LOG_ERROR << loc << "Not found";
                res.result(boost::beast::http::status::not_found);
                res.end();
                return;
            }
            std::filesystem::directory_iterator files(loc);

            for (auto &file : files)
            {
                std::ifstream readFile(file.path());
                if (!readFile.good())
                {
                    continue;
                }

                res.addHeader("Content-Type", "application/octet-stream");

                // Assuming only one dump file will be present in the dump id
                // directory
                std::string dumpFileName = file.path().filename().string();

                // Filename should be in alphanumeric, dot and underscore
                // Its based on phosphor-debug-collector application dumpfile
                // format
                std::regex dumpFileRegex("[a-zA-Z0-9\\._]+");
                if (!std::regex_match(dumpFileName, dumpFileRegex))
                {
                    BMCWEB_LOG_ERROR << "Invalid dump filename "
                                     << dumpFileName;
                    res.result(boost::beast::http::status::not_found);
                    res.end();
                    return;
                }
                std::string contentDispositionParam =
                    "attachment; filename=\"" + dumpFileName + "\"";

                res.addHeader("Content-Disposition", contentDispositionParam);

                res.body() = {std::istreambuf_iterator<char>(readFile),
                              std::istreambuf_iterator<char>()};
                res.end();
                return;
            }
            res.result(boost::beast::http::status::not_found);
            res.end();
            return;
        });

    BMCWEB_ROUTE(app, "/bus/system/<str>/")
        .requires({"Login"})
        .methods("GET"_method)([](const crow::Request &req, crow::Response &res,
                                  const std::string &Connection) {
            introspectObjects(Connection, "/",
                              std::make_shared<bmcweb::AsyncResp>(res));
        });

    BMCWEB_ROUTE(app, "/bus/system/<str>/<path>")
        .methods("GET"_method,
                 "POST"_method)([](const crow::Request &req,
                                   crow::Response &res,
                                   const std::string &processName,
                                   const std::string &requestedPath) {
            std::vector<std::string> strs;
            boost::split(strs, requestedPath, boost::is_any_of("/"));
            std::string objectPath;
            std::string interfaceName;
            std::string methodName;
            auto it = strs.begin();
            if (it == strs.end())
            {
                objectPath = "/";
            }
            while (it != strs.end())
            {
                // Check if segment contains ".".  If it does, it must be an
                // interface
                if (it->find(".") != std::string::npos)
                {
                    break;
                    // This check is neccesary as the trailing slash gets
                    // parsed as part of our <path> specifier above, which
                    // causes the normal trailing backslash redirector to
                    // fail.
                }
                else if (!it->empty())
                {
                    objectPath += "/" + *it;
                }
                it++;
            }
            if (it != strs.end())
            {
                interfaceName = *it;
                it++;

                // after interface, we might have a method name
                if (it != strs.end())
                {
                    methodName = *it;
                    it++;
                }
            }
            if (it != strs.end())
            {
                // if there is more levels past the method name, something
                // went wrong, return not found
                res.result(boost::beast::http::status::not_found);
                return;
            }
            if (interfaceName.empty())
            {
                std::shared_ptr<bmcweb::AsyncResp> asyncResp =
                    std::make_shared<bmcweb::AsyncResp>(res);

                crow::connections::systemBus->async_method_call(
                    [asyncResp, processName,
                     objectPath](const boost::system::error_code ec,
                                 const std::string &introspect_xml) {
                        if (ec)
                        {
                            BMCWEB_LOG_ERROR
                                << "Introspect call failed with error: "
                                << ec.message()
                                << " on process: " << processName
                                << " path: " << objectPath << "\n";
                            return;
                        }
                        tinyxml2::XMLDocument doc;

                        doc.Parse(introspect_xml.c_str());
                        tinyxml2::XMLNode *pRoot =
                            doc.FirstChildElement("node");
                        if (pRoot == nullptr)
                        {
                            BMCWEB_LOG_ERROR << "XML document failed to parse "
                                             << processName << " " << objectPath
                                             << "\n";
                            asyncResp->res.jsonValue = {
                                {"status", "XML parse error"}};
                            asyncResp->res.result(boost::beast::http::status::
                                                      internal_server_error);
                            return;
                        }

                        BMCWEB_LOG_DEBUG << introspect_xml;
                        asyncResp->res.jsonValue = {
                            {"status", "ok"},
                            {"bus_name", processName},
                            {"object_path", objectPath}};
                        nlohmann::json &interfacesArray =
                            asyncResp->res.jsonValue["interfaces"];
                        interfacesArray = nlohmann::json::array();
                        tinyxml2::XMLElement *interface =
                            pRoot->FirstChildElement("interface");

                        while (interface != nullptr)
                        {
                            const char *ifaceName =
                                interface->Attribute("name");
                            if (ifaceName != nullptr)
                            {
                                interfacesArray.push_back(
                                    {{"name", ifaceName}});
                            }

                            interface =
                                interface->NextSiblingElement("interface");
                        }
                    },
                    processName, objectPath,
                    "org.freedesktop.DBus.Introspectable", "Introspect");
            }
            else if (methodName.empty())
            {
                std::shared_ptr<bmcweb::AsyncResp> asyncResp =
                    std::make_shared<bmcweb::AsyncResp>(res);

                crow::connections::systemBus->async_method_call(
                    [asyncResp, processName, objectPath,
                     interfaceName](const boost::system::error_code ec,
                                    const std::string &introspect_xml) {
                        if (ec)
                        {
                            BMCWEB_LOG_ERROR
                                << "Introspect call failed with error: "
                                << ec.message()
                                << " on process: " << processName
                                << " path: " << objectPath << "\n";
                            return;
                        }
                        tinyxml2::XMLDocument doc;

                        doc.Parse(introspect_xml.data(), introspect_xml.size());
                        tinyxml2::XMLNode *pRoot =
                            doc.FirstChildElement("node");
                        if (pRoot == nullptr)
                        {
                            BMCWEB_LOG_ERROR << "XML document failed to parse "
                                             << processName << " " << objectPath
                                             << "\n";
                            asyncResp->res.result(boost::beast::http::status::
                                                      internal_server_error);
                            return;
                        }
                        asyncResp->res.jsonValue = {
                            {"status", "ok"},
                            {"bus_name", processName},
                            {"interface", interfaceName},
                            {"object_path", objectPath}};

                        nlohmann::json &methodsArray =
                            asyncResp->res.jsonValue["methods"];
                        methodsArray = nlohmann::json::array();

                        nlohmann::json &signalsArray =
                            asyncResp->res.jsonValue["signals"];
                        signalsArray = nlohmann::json::array();

                        nlohmann::json &propertiesObj =
                            asyncResp->res.jsonValue["properties"];
                        propertiesObj = nlohmann::json::object();

                        // if we know we're the only call, build the
                        // json directly
                        tinyxml2::XMLElement *interface =
                            pRoot->FirstChildElement("interface");
                        while (interface != nullptr)
                        {
                            const char *ifaceName =
                                interface->Attribute("name");

                            if (ifaceName != nullptr &&
                                ifaceName == interfaceName)
                            {
                                break;
                            }

                            interface =
                                interface->NextSiblingElement("interface");
                        }
                        if (interface == nullptr)
                        {
                            // if we got to the end of the list and
                            // never found a match, throw 404
                            asyncResp->res.result(
                                boost::beast::http::status::not_found);
                            return;
                        }

                        tinyxml2::XMLElement *methods =
                            interface->FirstChildElement("method");
                        while (methods != nullptr)
                        {
                            nlohmann::json argsArray = nlohmann::json::array();
                            tinyxml2::XMLElement *arg =
                                methods->FirstChildElement("arg");
                            while (arg != nullptr)
                            {
                                nlohmann::json thisArg;
                                for (const char *fieldName :
                                     std::array<const char *, 3>{
                                         "name", "direction", "type"})
                                {
                                    const char *fieldValue =
                                        arg->Attribute(fieldName);
                                    if (fieldValue != nullptr)
                                    {
                                        thisArg[fieldName] = fieldValue;
                                    }
                                }
                                argsArray.push_back(std::move(thisArg));
                                arg = arg->NextSiblingElement("arg");
                            }

                            const char *name = methods->Attribute("name");
                            if (name != nullptr)
                            {
                                methodsArray.push_back(
                                    {{"name", name},
                                     {"uri", "/bus/system/" + processName +
                                                 objectPath + "/" +
                                                 interfaceName + "/" + name},
                                     {"args", argsArray}});
                            }
                            methods = methods->NextSiblingElement("method");
                        }
                        tinyxml2::XMLElement *signals =
                            interface->FirstChildElement("signal");
                        while (signals != nullptr)
                        {
                            nlohmann::json argsArray = nlohmann::json::array();

                            tinyxml2::XMLElement *arg =
                                signals->FirstChildElement("arg");
                            while (arg != nullptr)
                            {
                                const char *name = arg->Attribute("name");
                                const char *type = arg->Attribute("type");
                                if (name != nullptr && type != nullptr)
                                {
                                    argsArray.push_back({
                                        {"name", name},
                                        {"type", type},
                                    });
                                }
                                arg = arg->NextSiblingElement("arg");
                            }
                            const char *name = signals->Attribute("name");
                            if (name != nullptr)
                            {
                                signalsArray.push_back(
                                    {{"name", name}, {"args", argsArray}});
                            }

                            signals = signals->NextSiblingElement("signal");
                        }

                        tinyxml2::XMLElement *property =
                            interface->FirstChildElement("property");
                        while (property != nullptr)
                        {
                            const char *name = property->Attribute("name");
                            const char *type = property->Attribute("type");
                            if (type != nullptr && name != nullptr)
                            {
                                sdbusplus::message::message m =
                                    crow::connections::systemBus
                                        ->new_method_call(processName.c_str(),
                                                          objectPath.c_str(),
                                                          "org.freedesktop."
                                                          "DBus."
                                                          "Properties",
                                                          "Get");
                                m.append(interfaceName, name);
                                nlohmann::json &propertyItem =
                                    propertiesObj[name];
                                crow::connections::systemBus->async_send(
                                    m, [&propertyItem, asyncResp](
                                           boost::system::error_code &ec,
                                           sdbusplus::message::message &m) {
                                        if (ec)
                                        {
                                            return;
                                        }

                                        convertDBusToJSON("v", m, propertyItem);
                                    });
                            }
                            property = property->NextSiblingElement("property");
                        }
                    },
                    processName, objectPath,
                    "org.freedesktop.DBus.Introspectable", "Introspect");
            }
            else
            {
                if (req.method() != "POST"_method)
                {
                    res.result(boost::beast::http::status::not_found);
                    res.end();
                    return;
                }

                nlohmann::json requestDbusData =
                    nlohmann::json::parse(req.body, nullptr, false);

                if (requestDbusData.is_discarded())
                {
                    res.result(boost::beast::http::status::bad_request);
                    res.end();
                    return;
                }
                if (!requestDbusData.is_array())
                {
                    res.result(boost::beast::http::status::bad_request);
                    res.end();
                    return;
                }
                auto transaction = std::make_shared<InProgressActionData>(res);

                transaction->path = objectPath;
                transaction->methodName = methodName;
                transaction->arguments = std::move(requestDbusData);

                findActionOnInterface(transaction, processName);
            }
        });
}
} // namespace openbmc_mapper
} // namespace crow
