// 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 <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 <sdbusplus/message/types.hpp>

#include <filesystem>
#include <fstream>
#include <regex>

namespace crow
{
namespace openbmc_mapper
{

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

const char* notFoundMsg = "404 Not Found";
const char* badReqMsg = "400 Bad Request";
const char* methodNotAllowedMsg = "405 Method Not Allowed";
const char* forbiddenMsg = "403 Forbidden";
const char* methodFailedMsg = "500 Method Call Failed";
const char* methodOutputFailedMsg = "500 Method Output Error";
const char* notFoundDesc =
    "org.freedesktop.DBus.Error.FileNotFound: path or object not found";
const char* propNotFoundDesc = "The specified property cannot be found";
const char* noJsonDesc = "No JSON object could be decoded";
const char* methodNotFoundDesc = "The specified method cannot be found";
const char* methodNotAllowedDesc = "Method not allowed";
const char* forbiddenPropDesc = "The specified property cannot be created";
const char* forbiddenResDesc = "The specified resource cannot be created";

void setErrorResponse(crow::Response& res, boost::beast::http::status result,
                      const std::string& desc, const std::string_view 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.emplace_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.emplace_back("");
                    }
                }
                break;
            default:
                if (containerDepth == 0)
                {
                    if (character + 1 != string.end())
                    {
                        ret.emplace_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 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 (intValue == nullptr)
        {
            const uint64_t* uintValue = j->get_ptr<const uint64_t*>();
            if (uintValue != nullptr)
            {
                v = static_cast<int64_t>(*uintValue);
                intValue = &v;
            }
        }
        if (doubleValue == nullptr)
        {
            const uint64_t* uintValue = j->get_ptr<const uint64_t*>();
            if (uintValue != nullptr)
            {
                d = static_cast<double>(*uintValue);
                doubleValue = &d;
            }
        }
        if (doubleValue == nullptr)
        {
            if (intValue != 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], static_cast<const void*>(stringValue->data()));
            if (r < 0)
            {
                return r;
            }
        }
        else if (argCode == "i")
        {
            if (intValue == nullptr)
            {
                return -1;
            }
            if ((*intValue < std::numeric_limits<int32_t>::lowest()) ||
                (*intValue > std::numeric_limits<int32_t>::max()))
            {
                return -ERANGE;
            }
            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)
            {
                if (*intValue == 1)
                {
                    boolInt = true;
                }
                else if (*intValue == 0)
                {
                    boolInt = false;
                }
                else
                {
                    return -ERANGE;
                }
            }
            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;
            }
            if ((*intValue < std::numeric_limits<int16_t>::lowest()) ||
                (*intValue > std::numeric_limits<int16_t>::max()))
            {
                return -ERANGE;
            }
            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;
            }
            if ((*intValue < std::numeric_limits<int64_t>::lowest()) ||
                (*intValue > std::numeric_limits<int64_t>::max()))
            {
                return -ERANGE;
            }
            r = sd_bus_message_append_basic(m, argCode[0], intValue);
            if (r < 0)
            {
                return r;
            }
        }
        else if (argCode == "y")
        {
            const uint64_t* uintValue = j->get_ptr<const uint64_t*>();
            if (uintValue == nullptr)
            {
                return -1;
            }
            if ((*uintValue < std::numeric_limits<uint8_t>::lowest()) ||
                (*uintValue > std::numeric_limits<uint8_t>::max()))
            {
                return -ERANGE;
            }
            uint8_t y = static_cast<uint8_t>(*uintValue);
            r = sd_bus_message_append_basic(m, argCode[0], &y);
        }
        else if (argCode == "q")
        {
            const uint64_t* uintValue = j->get_ptr<const uint64_t*>();
            if (uintValue == nullptr)
            {
                return -1;
            }
            if ((*uintValue < std::numeric_limits<uint16_t>::lowest()) ||
                (*uintValue > std::numeric_limits<uint16_t>::max()))
            {
                return -ERANGE;
            }
            uint16_t q = static_cast<uint16_t>(*uintValue);
            r = sd_bus_message_append_basic(m, argCode[0], &q);
        }
        else if (argCode == "u")
        {
            const uint64_t* uintValue = j->get_ptr<const uint64_t*>();
            if (uintValue == nullptr)
            {
                return -1;
            }
            if ((*uintValue < std::numeric_limits<uint32_t>::lowest()) ||
                (*uintValue > std::numeric_limits<uint32_t>::max()))
            {
                return -ERANGE;
            }
            uint32_t u = static_cast<uint32_t>(*uintValue);
            r = sd_bus_message_append_basic(m, argCode[0], &u);
        }
        else if (argCode == "t")
        {
            const uint64_t* uintValue = j->get_ptr<const uint64_t*>();
            if (uintValue == nullptr)
            {
                return -1;
            }
            if ((*uintValue < std::numeric_limits<uint64_t>::lowest()) ||
                (*uintValue > std::numeric_limits<uint64_t>::max()))
            {
                return -ERANGE;
            }
            r = sd_bus_message_append_basic(m, argCode[0], uintValue);
        }
        else if (argCode == "d")
        {
            if (doubleValue == nullptr)
            {
                return -1;
            }
            if ((*doubleValue < std::numeric_limits<double>::lowest()) ||
                (*doubleValue > std::numeric_limits<double>::max()))
            {
                return -ERANGE;
            }
            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(), nullptr, &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, 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)
                                        {
                                            if (r == -ERANGE)
                                            {
                                                transaction->setErrorStatus(
                                                    "Provided property value "
                                                    "is out of range for the "
                                                    "property type");
                                            }
                                            else
                                            {
                                                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() == boost::beast::http::verb::post)
    {
        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() == boost::beast::http::verb::get)
    {
        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() == boost::beast::http::verb::put)
    {
        handlePut(req, res, objectPath, destProperty);
        return;
    }
    else if (req.method() == boost::beast::http::verb::delete_)
    {
        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(boost::beast::http::verb::get)(
            [](const crow::Request& req, crow::Response& res) {
                res.jsonValue = {{"buses", {{{"name", "system"}}}},
                                 {"status", "ok"}};
                res.end();
            });

    BMCWEB_ROUTE(app, "/bus/system/")
        .requires({"Login"})
        .methods(boost::beast::http::verb::get)(
            [](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(boost::beast::http::verb::get)(
            [](const crow::Request& req, crow::Response& res) {
                handleList(res, "/");
            });

    BMCWEB_ROUTE(app, "/xyz/<path>")
        .requires({"Login"})
        .methods(boost::beast::http::verb::get)([](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(boost::beast::http::verb::put, boost::beast::http::verb::post,
                 boost::beast::http::verb::delete_)(
            [](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(boost::beast::http::verb::get)([](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(boost::beast::http::verb::put, boost::beast::http::verb::post,
                 boost::beast::http::verb::delete_)(
            [](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(boost::beast::http::verb::get)([](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(boost::beast::http::verb::get)(
            [](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>")
        .requires({"ConfigureComponents", "ConfigureManager"})
        .methods(
            boost::beast::http::verb::get,
            boost::beast::http::verb::post)([](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 necessary 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);
                res.end();
                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& e,
                                           sdbusplus::message::message& msg) {
                                        if (e)
                                        {
                                            return;
                                        }

                                        convertDBusToJSON("v", msg,
                                                          propertyItem);
                                    });
                            }
                            property = property->NextSiblingElement("property");
                        }
                    },
                    processName, objectPath,
                    "org.freedesktop.DBus.Introspectable", "Introspect");
            }
            else
            {
                if (req.method() != boost::beast::http::verb::post)
                {
                    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
