// 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.hpp"
#include "async_resp.hpp"
#include "boost_formatters.hpp"
#include "dbus_singleton.hpp"
#include "dbus_utility.hpp"
#include "http_request.hpp"
#include "http_response.hpp"
#include "json_formatters.hpp"
#include "logging.hpp"
#include "parsing.hpp"
#include "routing.hpp"
#include "str_utility.hpp"

#include <systemd/sd-bus-protocol.h>
#include <systemd/sd-bus.h>
#include <tinyxml2.h>

#include <boost/beast/http/status.hpp>
#include <boost/beast/http/verb.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/container/vector.hpp>
#include <boost/system/error_code.hpp>
#include <nlohmann/json.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/exception.hpp>
#include <sdbusplus/message.hpp>
#include <sdbusplus/message/native_types.hpp>

#include <algorithm>
#include <array>
#include <cerrno>
#include <cstdint>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <functional>
#include <initializer_list>
#include <iterator>
#include <limits>
#include <map>
#include <memory>
#include <ranges>
#include <regex>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>

// IWYU pragma: no_include <boost/algorithm/string/detail/classification.hpp>
// IWYU pragma: no_include <boost/system/detail/error_code.hpp>
// IWYU pragma: no_include <boost/system/detail/error_category.hpp>
// IWYU pragma: no_include <errno.h>
// IWYU pragma: no_include <string.h>
// IWYU pragma: no_include <ext/alloc_traits.h>
// IWYU pragma: no_include <exception>
// IWYU pragma: no_include <boost/type_index/type_index_facade.hpp>

namespace crow
{
namespace openbmc_mapper
{
const constexpr char* notFoundMsg = "404 Not Found";
const constexpr char* badReqMsg = "400 Bad Request";
const constexpr char* methodNotAllowedMsg = "405 Method Not Allowed";
const constexpr char* forbiddenMsg = "403 Forbidden";
const constexpr char* unsupportedMediaMsg = "415 Unsupported Media Type";
const constexpr char* methodFailedMsg = "500 Method Call Failed";
const constexpr char* methodOutputFailedMsg = "500 Method Output Error";
const constexpr char* notFoundDesc =
    "org.freedesktop.DBus.Error.FileNotFound: path or object not found";
const constexpr char* propNotFoundDesc =
    "The specified property cannot be found";
const constexpr char* noJsonDesc = "No JSON object could be decoded";
const constexpr char* invalidContentType =
    "Content-type header is missing or invalid";
const constexpr char* methodNotFoundDesc =
    "The specified method cannot be found";
const constexpr char* methodNotAllowedDesc = "Method not allowed";
const constexpr char* forbiddenPropDesc =
    "The specified property cannot be created";
const constexpr char* forbiddenResDesc =
    "The specified resource cannot be created";

inline bool validateFilename(const std::string& filename)
{
    static std::regex validFilename(R"(^[\w\- ]+(\.?[\w\- ]*)$)");

    return std::regex_match(filename, validFilename);
}

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

inline void
    introspectObjects(const std::string& processName,
                      const std::string& objectPath,
                      const std::shared_ptr<bmcweb::AsyncResp>& transaction)
{
    if (transaction->res.jsonValue.is_null())
    {
        transaction->res.jsonValue["status"] = "ok";
        transaction->res.jsonValue["bus_name"] = processName;
        transaction->res.jsonValue["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& introspectXml) {
        if (ec)
        {
            BMCWEB_LOG_ERROR(
                "Introspect call failed with error: {} on process: {} path: {}",
                ec.message(), processName, objectPath);
            return;
        }
        nlohmann::json::object_t object;
        object["path"] = objectPath;

        transaction->res.jsonValue["objects"].emplace_back(std::move(object));

        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 {} {}", processName,
                             objectPath);
        }
        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");
}

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

    sdbusplus::asio::getAllProperties(
        *crow::connections::systemBus, service, objectPath, interface,
        [asyncResp, objectPath, service,
         interface](const boost::system::error_code& ec,
                    const dbus::utility::DBusPropertiesMap& propertiesList) {
        if (ec)
        {
            BMCWEB_LOG_ERROR(
                "GetAll on path {} iface {} service {} failed with code {}",
                objectPath, interface, service, 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) {
                if constexpr (std::is_same_v<std::decay_t<decltype(val)>,
                                             sdbusplus::message::unix_fd>)
                {
                    propertyJson = val.fd;
                }
                else
                {
                    propertyJson = val;
                }
            },
                value);
        }
    });
}

// Find any results that weren't picked up by ObjectManagers, to be
// called after all ObjectManagers are searched for and called.
inline void findRemainingObjectsForEnumerate(
    const std::string& objectPath,
    const std::shared_ptr<dbus::utility::MapperGetSubTreeResponse>& subtree,
    const 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 (!interface.starts_with("org.freedesktop.DBus"))
                    {
                        getPropertiesForEnumerate(path, service, interface,
                                                  asyncResp);
                    }
                }
            }
        }
    }
}

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

    ~InProgressEnumerateData()
    {
        try
        {
            findRemainingObjectsForEnumerate(objectPath, subtree, asyncResp);
        }
        catch (...)
        {
            BMCWEB_LOG_CRITICAL(
                "findRemainingObjectsForEnumerate threw exception");
        }
    }

    InProgressEnumerateData(const InProgressEnumerateData&) = delete;
    InProgressEnumerateData(InProgressEnumerateData&&) = delete;
    InProgressEnumerateData& operator=(const InProgressEnumerateData&) = delete;
    InProgressEnumerateData& operator=(InProgressEnumerateData&&) = delete;
    const std::string objectPath;
    std::shared_ptr<dbus::utility::MapperGetSubTreeResponse> subtree;
    std::shared_ptr<bmcweb::AsyncResp> asyncResp;
};

inline void getManagedObjectsForEnumerate(
    const std::string& objectName, const std::string& objectManagerPath,
    const std::string& connectionName,
    const std::shared_ptr<InProgressEnumerateData>& transaction)
{
    BMCWEB_LOG_DEBUG(
        "getManagedObjectsForEnumerate {} object_manager_path {} connection_name {}",
        objectName, objectManagerPath, connectionName);
    sdbusplus::message::object_path path(objectManagerPath);
    dbus::utility::getManagedObjects(
        connectionName, path,
        [transaction, objectName,
         connectionName](const boost::system::error_code& ec,
                         const dbus::utility::ManagedObjectType& objects) {
        if (ec)
        {
            BMCWEB_LOG_ERROR(
                "GetManagedObjects on path {} on connection {} failed with code {}",
                objectName, connectionName, ec);
            return;
        }

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

        for (const auto& objectPath : objects)
        {
            if (objectPath.first.str.starts_with(objectName))
            {
                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) {
                            if constexpr (std::is_same_v<
                                              std::decay_t<decltype(val)>,
                                              sdbusplus::message::unix_fd>)
                            {
                                propertyJson = val.fd;
                            }
                            else
                            {
                                propertyJson = val;
                            }
                        },
                            property.second);
                    }
                }
            }
            for (const auto& interface : objectPath.second)
            {
                if (interface.first == "org.freedesktop.DBus.ObjectManager")
                {
                    getManagedObjectsForEnumerate(objectPath.first.str,
                                                  objectPath.first.str,
                                                  connectionName, transaction);
                }
            }
        }
    });
}

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

        for (const auto& pathGroup : objects)
        {
            for (const auto& connectionGroup : pathGroup.second)
            {
                if (connectionGroup.first == connectionName)
                {
                    // Found the object manager path for this resource.
                    getManagedObjectsForEnumerate(objectName, pathGroup.first,
                                                  connectionName, transaction);
                    return;
                }
            }
        }
    },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetAncestors", objectName,
        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.
inline void getObjectAndEnumerate(
    const std::shared_ptr<InProgressEnumerateData>& transaction)
{
    dbus::utility::getDbusObject(
        transaction->objectPath, {},
        [transaction](const boost::system::error_code& ec,
                      const dbus::utility::MapperGetObject& objects) {
        if (ec)
        {
            BMCWEB_LOG_ERROR("GetObject for path {} failed with code {}",
                             transaction->objectPath, ec);
            return;
        }

        BMCWEB_LOG_DEBUG("GetObject for {} has {} entries",
                         transaction->objectPath, objects.size());
        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, std::less<>,
            std::vector<std::pair<std::string, std::string>>>
            connections;

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

        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);
            }
        }
    });
}

// Structure for storing data on an in progress action
struct InProgressActionData
{
    explicit InProgressActionData(
        const std::shared_ptr<bmcweb::AsyncResp>& res) :
        asyncResp(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 (asyncResp->res.result() == boost::beast::http::status::ok)
        {
            if (!methodPassed)
            {
                if (!methodFailed)
                {
                    setErrorResponse(asyncResp->res,
                                     boost::beast::http::status::not_found,
                                     methodNotFoundDesc, notFoundMsg);
                }
            }
            else
            {
                if (outputFailed)
                {
                    setErrorResponse(
                        asyncResp->res,
                        boost::beast::http::status::internal_server_error,
                        "Method output failure", methodOutputFailedMsg);
                }
                else
                {
                    asyncResp->res.jsonValue["status"] = "ok";
                    asyncResp->res.jsonValue["message"] = "200 OK";
                    asyncResp->res.jsonValue["data"] = methodResponse;
                }
            }
        }
    }
    InProgressActionData(const InProgressActionData&) = delete;
    InProgressActionData(InProgressActionData&&) = delete;
    InProgressActionData& operator=(const InProgressActionData&) = delete;
    InProgressActionData& operator=(InProgressActionData&&) = delete;

    void setErrorStatus(const std::string& desc)
    {
        setErrorResponse(asyncResp->res,
                         boost::beast::http::status::bad_request, desc,
                         badReqMsg);
    }
    std::shared_ptr<bmcweb::AsyncResp> asyncResp;
    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;
};

inline 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;
}

inline int convertJsonToDbus(sd_bus_message* m, const std::string& argType,
                             const nlohmann::json& inputJson)
{
    int r = 0;
    BMCWEB_LOG_DEBUG("Converting {} to type: {}", inputJson, argType);
    const std::vector<std::string> argTypes = dbusArgSplit(argType);

    // Assume a single object for now.
    const nlohmann::json* j = &inputJson;
    nlohmann::json::const_iterator jIt = inputJson.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 == inputJson.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 = 0;
            if (intValue != nullptr)
            {
                if (*intValue == 1)
                {
                    boolInt = 1;
                }
                else if (*intValue == 0)
                {
                    boolInt = 0;
                }
                else
                {
                    return -ERANGE;
                }
            }
            else if (b != nullptr)
            {
                boolInt = *b ? 1 : 0;
            }
            else if (stringValue != nullptr)
            {
                if (!stringValue->empty())
                {
                    if (stringValue->front() == 't' ||
                        stringValue->front() == 'T')
                    {
                        boolInt = 1;
                    }
                }
            }
            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;
            }
            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>::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>::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>::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;
            }
            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;
            }
            r = sd_bus_message_append_basic(m, argCode[0], doubleValue);
            if (r < 0)
            {
                return r;
            }
        }
        else if (argCode.starts_with("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 (const auto& it : *j)
            {
                r = convertJsonToDbus(m, containedType, it);
                if (r < 0)
                {
                    return r;
                }
            }
            sd_bus_message_close_container(m);
        }
        else if (argCode.starts_with("v"))
        {
            std::string containedType = argCode.substr(1);
            BMCWEB_LOG_DEBUG("variant type: {} appending variant of type: {}",
                             argCode, containedType);
            r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT,
                                              containedType.c_str());
            if (r < 0)
            {
                return r;
            }

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

            r = sd_bus_message_close_container(m);
            if (r < 0)
            {
                return r;
            }
        }
        else if (argCode.starts_with("(") && argCode.ends_with(")"))
        {
            std::string containedType = argCode.substr(1, argCode.size() - 2);
            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& argCode2 : dbusArgSplit(containedType))
            {
                if (it == j->end())
                {
                    return -1;
                }
                r = convertJsonToDbus(m, argCode2, *it);
                if (r < 0)
                {
                    return r;
                }
                it++;
            }
            r = sd_bus_message_close_container(m);
        }
        else if (argCode.starts_with("{") && argCode.ends_with("}"))
        {
            std::string containedType = argCode.substr(1, argCode.size() - 2);
            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& keyType = codes[0];
            const std::string& valueType = codes[1];
            for (const auto& it : j->items())
            {
                r = convertJsonToDbus(m, keyType, it.key());
                if (r < 0)
                {
                    return r;
                }

                r = convertJsonToDbus(m, valueType, 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_t& m,
                    nlohmann::json& data)
{
    T value;
    // When T == char*, this warning fires.  Unclear how to resolve
    // Given that sd-bus takes a void pointer to a char*, and that's
    // Not something we can fix.
    // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion)
    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 {} failed!",
                         typeCode);
        return r;
    }

    data = value;
    return 0;
}

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

inline int readDictEntryFromMessage(const std::string& typeCode,
                                    sdbusplus::message_t& 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(2, ' ', true, nlohmann::json::error_handler_t::replace);
        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;
}

inline int readArrayFromMessage(const std::string& typeCode,
                                sdbusplus::message_t& m, nlohmann::json& data)
{
    if (typeCode.size() < 2)
    {
        BMCWEB_LOG_ERROR("Type code {} too small for an array", typeCode);
        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 = containedType.starts_with("{") && containedType.ends_with("}");

    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(), 0);
        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;
}

inline int readStructFromMessage(const std::string& typeCode,
                                 sdbusplus::message_t& m, nlohmann::json& data)
{
    if (typeCode.size() < 3)
    {
        BMCWEB_LOG_ERROR("Type code {} too small for a struct", typeCode);
        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;
}

inline int readVariantFromMessage(sdbusplus::message_t& m, nlohmann::json& data)
{
    const char* containerType = nullptr;
    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;
}

inline int convertDBusToJSON(const std::string& returnType,
                             sdbusplus::message_t& 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" || typeCode == "g" || 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 (typeCode.starts_with("a"))
        {
            r = readArrayFromMessage(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (typeCode.starts_with("(") && typeCode.ends_with(")"))
        {
            r = readStructFromMessage(typeCode, m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else if (typeCode.starts_with("v"))
        {
            r = readVariantFromMessage(m, *thisElement);
            if (r < 0)
            {
                return r;
            }
        }
        else
        {
            BMCWEB_LOG_ERROR("Invalid D-Bus signature type {}", typeCode);
            return -2;
        }
    }

    return 0;
}

inline void handleMethodResponse(
    const std::shared_ptr<InProgressActionData>& transaction,
    sdbusplus::message_t& 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.emplace_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.emplace_back(std::move(j));
        transaction->methodResponse.emplace_back(std::move(data));
        transaction->convertedToArray = true;
    }
    else
    {
        transaction->methodResponse.emplace_back(std::move(data));
    }
}

inline void findActionOnInterface(
    const 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& introspectXml) {
        BMCWEB_LOG_DEBUG("got xml:\n {}", introspectXml);
        if (ec)
        {
            BMCWEB_LOG_ERROR(
                "Introspect call failed with error: {} on process: {}",
                ec.message(), connectionName);
            return;
        }
        tinyxml2::XMLDocument doc;

        doc.Parse(introspectXml.data(), introspectXml.size());
        tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
        if (pRoot == nullptr)
        {
            BMCWEB_LOG_ERROR("XML document failed to parse {}", connectionName);
            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 {} on interface {}",
                            thisMethodName, thisInterfaceName);
                        sdbusplus::message_t 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");
                        }

                        auto 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](
                                   const boost::system::error_code& ec2,
                                   sdbusplus::message_t& m2) {
                            if (ec2)
                            {
                                transaction->methodFailed = true;
                                const sd_bus_error* e = m2.get_error();

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

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

inline void handleAction(const crow::Request& req,
                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                         const std::string& objectPath,
                         const std::string& methodName)
{
    BMCWEB_LOG_DEBUG("handleAction on path: {} and method {}", objectPath,
                     methodName);
    nlohmann::json requestDbusData;

    JsonParseResult ret = parseRequestAsJson(req, requestDbusData);
    if (ret == JsonParseResult::BadContentType)
    {
        setErrorResponse(asyncResp->res,
                         boost::beast::http::status::unsupported_media_type,
                         invalidContentType, unsupportedMediaMsg);
        return;
    }
    if (ret != JsonParseResult::Success)
    {
        setErrorResponse(asyncResp->res,
                         boost::beast::http::status::bad_request, noJsonDesc,
                         badReqMsg);
        return;
    }
    nlohmann::json::iterator data = requestDbusData.find("data");
    if (data == requestDbusData.end())
    {
        setErrorResponse(asyncResp->res,
                         boost::beast::http::status::bad_request, noJsonDesc,
                         badReqMsg);
        return;
    }

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

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

        BMCWEB_LOG_DEBUG("GetObject returned {} object(s)",
                         interfaceNames.size());

        for (const std::pair<std::string, std::vector<std::string>>& object :
             interfaceNames)
        {
            findActionOnInterface(transaction, object.first);
        }
    });
}

inline void handleDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                         const std::string& objectPath)
{
    BMCWEB_LOG_DEBUG("handleDelete on path: {}", objectPath);

    dbus::utility::getDbusObject(
        objectPath, {},
        [asyncResp, objectPath](
            const boost::system::error_code& ec,
            const std::vector<std::pair<std::string, std::vector<std::string>>>&
                interfaceNames) {
        if (ec || interfaceNames.empty())
        {
            BMCWEB_LOG_ERROR("Can't find object");
            setErrorResponse(asyncResp->res,
                             boost::beast::http::status::method_not_allowed,
                             methodNotAllowedDesc, methodNotAllowedMsg);
            return;
        }

        auto transaction = std::make_shared<InProgressActionData>(asyncResp);
        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);
        }
    });
}

inline void handleList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const std::string& objectPath, int32_t depth = 0)
{
    dbus::utility::getSubTreePaths(
        objectPath, depth, {},
        [asyncResp](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreePathsResponse& objectPaths) {
        if (ec)
        {
            setErrorResponse(asyncResp->res,
                             boost::beast::http::status::not_found,
                             notFoundDesc, notFoundMsg);
        }
        else
        {
            asyncResp->res.jsonValue["status"] = "ok";
            asyncResp->res.jsonValue["message"] = "200 OK";
            asyncResp->res.jsonValue["data"] = objectPaths;
        }
    });
}

inline void handleEnumerate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                            const std::string& objectPath)
{
    BMCWEB_LOG_DEBUG("Doing enumerate on {}", objectPath);

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

    dbus::utility::getSubTree(
        objectPath, 0, {},
        [objectPath, asyncResp](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreeResponse& objectNames) {
        auto transaction = std::make_shared<InProgressEnumerateData>(objectPath,
                                                                     asyncResp);

        transaction->subtree =
            std::make_shared<dbus::utility::MapperGetSubTreeResponse>(
                objectNames);

        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);
    });
}

inline void handleGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                      std::string& objectPath, std::string& destProperty)
{
    BMCWEB_LOG_DEBUG("handleGet: {} prop:{}", objectPath, 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));

    dbus::utility::getDbusObject(
        *path, {},
        [asyncResp, path,
         propertyName](const boost::system::error_code& ec,
                       const dbus::utility::MapperGetObject& objectNames) {
        if (ec || objectNames.empty())
        {
            setErrorResponse(asyncResp->res,
                             boost::beast::http::status::not_found,
                             notFoundDesc, notFoundMsg);
            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 : objectNames)
        {
            const std::vector<std::string>& interfaceNames = connection.second;

            if (interfaceNames.empty())
            {
                setErrorResponse(asyncResp->res,
                                 boost::beast::http::status::not_found,
                                 notFoundDesc, notFoundMsg);
                return;
            }

            for (const std::string& interface : interfaceNames)
            {
                sdbusplus::message_t 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, [asyncResp, response,
                        propertyName](const boost::system::error_code& ec2,
                                      sdbusplus::message_t& msg) {
                    if (ec2)
                    {
                        BMCWEB_LOG_ERROR("Bad dbus request error: {}", ec2);
                    }
                    else
                    {
                        nlohmann::json properties;
                        int r = convertDBusToJSON("a{sv}", msg, properties);
                        if (r < 0)
                        {
                            BMCWEB_LOG_ERROR("convertDBusToJSON failed");
                        }
                        else
                        {
                            for (const 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(
                                asyncResp->res,
                                boost::beast::http::status::not_found,
                                propNotFoundDesc, notFoundMsg);
                        }
                        else
                        {
                            asyncResp->res.jsonValue["status"] = "ok";
                            asyncResp->res.jsonValue["message"] = "200 OK";
                            asyncResp->res.jsonValue["data"] = *response;
                        }
                    }
                });
            }
        }
    });
}

struct AsyncPutRequest
{
    explicit AsyncPutRequest(const std::shared_ptr<bmcweb::AsyncResp>& resIn) :
        asyncResp(resIn)
    {}
    ~AsyncPutRequest()
    {
        if (asyncResp->res.jsonValue.empty())
        {
            setErrorResponse(asyncResp->res,
                             boost::beast::http::status::forbidden,
                             forbiddenMsg, forbiddenPropDesc);
        }
    }

    AsyncPutRequest(const AsyncPutRequest&) = delete;
    AsyncPutRequest(AsyncPutRequest&&) = delete;
    AsyncPutRequest& operator=(const AsyncPutRequest&) = delete;
    AsyncPutRequest& operator=(AsyncPutRequest&&) = delete;

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

    const std::shared_ptr<bmcweb::AsyncResp> asyncResp;
    std::string objectPath;
    std::string propertyName;
    nlohmann::json propertyValue;
};

inline void handlePut(const crow::Request& req,
                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                      const std::string& objectPath,
                      const std::string& destProperty)
{
    if (destProperty.empty())
    {
        setErrorResponse(asyncResp->res, boost::beast::http::status::forbidden,
                         forbiddenResDesc, forbiddenMsg);
        return;
    }
    nlohmann::json requestDbusData;

    JsonParseResult ret = parseRequestAsJson(req, requestDbusData);
    if (ret == JsonParseResult::BadContentType)
    {
        setErrorResponse(asyncResp->res,
                         boost::beast::http::status::unsupported_media_type,
                         invalidContentType, unsupportedMediaMsg);
        return;
    }

    if (ret != JsonParseResult::Success)
    {
        setErrorResponse(asyncResp->res,
                         boost::beast::http::status::bad_request, noJsonDesc,
                         badReqMsg);
        return;
    }

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

    dbus::utility::getDbusObject(
        transaction->objectPath, {},
        [transaction](const boost::system::error_code& ec2,
                      const dbus::utility::MapperGetObject& objectNames) {
        if (!ec2 && objectNames.empty())
        {
            setErrorResponse(transaction->asyncResp->res,
                             boost::beast::http::status::not_found,
                             propNotFoundDesc, notFoundMsg);
            return;
        }

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

            crow::connections::systemBus->async_method_call(
                [connectionName{std::string(connectionName)},
                 transaction](const boost::system::error_code& ec3,
                              const std::string& introspectXml) {
                if (ec3)
                {
                    BMCWEB_LOG_ERROR(
                        "Introspect call failed with error: {} on process: {}",
                        ec3.message(), 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_t 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](
                                           const boost::system::error_code& ec,
                                           sdbusplus::message_t& m2) {
                                    BMCWEB_LOG_DEBUG("sent");
                                    if (ec)
                                    {
                                        const sd_bus_error* e = m2.get_error();
                                        setErrorResponse(
                                            transaction->asyncResp->res,
                                            boost::beast::http::status::
                                                forbidden,
                                            (e) != nullptr
                                                ? e->name
                                                : ec.category().name(),
                                            (e) != nullptr ? e->message
                                                           : ec.message());
                                    }
                                    else
                                    {
                                        transaction->asyncResp->res
                                            .jsonValue["status"] = "ok";
                                        transaction->asyncResp->res
                                            .jsonValue["message"] = "200 OK";
                                        transaction->asyncResp->res
                                            .jsonValue["data"] = nullptr;
                                    }
                                });
                            }
                        }
                        propNode = propNode->NextSiblingElement("property");
                    }
                    ifaceNode = ifaceNode->NextSiblingElement("interface");
                }
            },
                connectionName, transaction->objectPath,
                "org.freedesktop.DBus.Introspectable", "Introspect");
        }
    });
}

inline void handleDBusUrl(const crow::Request& req,
                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          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 != std::string::npos)
    {
        destProperty = objectPath.substr(attrPosition + strlen(attrSeperator),
                                         objectPath.length());
        objectPath.resize(attrPosition);
    }

    if (req.method() == boost::beast::http::verb::post)
    {
        constexpr const char* actionSeperator = "/action/";
        size_t actionPosition = objectPath.find(actionSeperator);
        if (actionPosition != std::string::npos)
        {
            std::string postProperty =
                objectPath.substr((actionPosition + strlen(actionSeperator)),
                                  objectPath.length());
            objectPath.resize(actionPosition);
            handleAction(req, asyncResp, objectPath, postProperty);
            return;
        }
    }
    else if (req.method() == boost::beast::http::verb::get)
    {
        if (objectPath.ends_with("/enumerate"))
        {
            objectPath.erase(objectPath.end() - sizeof("enumerate"),
                             objectPath.end());
            handleEnumerate(asyncResp, objectPath);
        }
        else if (objectPath.ends_with("/list"))
        {
            objectPath.erase(objectPath.end() - sizeof("list"),
                             objectPath.end());
            handleList(asyncResp, objectPath);
        }
        else
        {
            // Trim any trailing "/" at the end
            if (objectPath.ends_with("/"))
            {
                objectPath.pop_back();
                handleList(asyncResp, objectPath, 1);
            }
            else
            {
                handleGet(asyncResp, objectPath, destProperty);
            }
        }
        return;
    }
    else if (req.method() == boost::beast::http::verb::put)
    {
        handlePut(req, asyncResp, objectPath, destProperty);
        return;
    }
    else if (req.method() == boost::beast::http::verb::delete_)
    {
        handleDelete(asyncResp, objectPath);
        return;
    }

    setErrorResponse(asyncResp->res,
                     boost::beast::http::status::method_not_allowed,
                     methodNotAllowedDesc, methodNotAllowedMsg);
}

inline void
    handleBusSystemPost(const crow::Request& req,
                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                        const std::string& processName,
                        const std::string& requestedPath)
{
    std::vector<std::string> strs;

    bmcweb::split(strs, requestedPath, '/');
    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.
        }
        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
        asyncResp->res.result(boost::beast::http::status::not_found);
        return;
    }
    if (interfaceName.empty())
    {
        crow::connections::systemBus->async_method_call(
            [asyncResp, processName,
             objectPath](const boost::system::error_code& ec,
                         const std::string& introspectXml) {
            if (ec)
            {
                BMCWEB_LOG_ERROR(
                    "Introspect call failed with error: {} on process: {} path: {}",
                    ec.message(), processName, objectPath);
                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 {} {}",
                                 processName, objectPath);
                asyncResp->res.jsonValue["status"] = "XML parse error";
                asyncResp->res.result(
                    boost::beast::http::status::internal_server_error);
                return;
            }

            BMCWEB_LOG_DEBUG("{}", introspectXml);
            asyncResp->res.jsonValue["status"] = "ok";
            asyncResp->res.jsonValue["bus_name"] = processName;
            asyncResp->res.jsonValue["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)
                {
                    nlohmann::json::object_t interfaceObj;
                    interfaceObj["name"] = ifaceName;
                    interfacesArray.emplace_back(std::move(interfaceObj));
                }

                interface = interface->NextSiblingElement("interface");
            }
        },
            processName, objectPath, "org.freedesktop.DBus.Introspectable",
            "Introspect");
    }
    else if (methodName.empty())
    {
        crow::connections::systemBus->async_method_call(
            [asyncResp, processName, objectPath,
             interfaceName](const boost::system::error_code& ec,
                            const std::string& introspectXml) {
            if (ec)
            {
                BMCWEB_LOG_ERROR(
                    "Introspect call failed with error: {} on process: {} path: {}",
                    ec.message(), processName, objectPath);
                return;
            }
            tinyxml2::XMLDocument doc;

            doc.Parse(introspectXml.data(), introspectXml.size());
            tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
            if (pRoot == nullptr)
            {
                BMCWEB_LOG_ERROR("XML document failed to parse {} {}",
                                 processName, objectPath);
                asyncResp->res.result(
                    boost::beast::http::status::internal_server_error);
                return;
            }

            asyncResp->res.jsonValue["status"] = "ok";
            asyncResp->res.jsonValue["bus_name"] = processName;
            asyncResp->res.jsonValue["interface"] = interfaceName;
            asyncResp->res.jsonValue["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.emplace_back(std::move(thisArg));
                    arg = arg->NextSiblingElement("arg");
                }

                const char* name = methods->Attribute("name");
                if (name != nullptr)
                {
                    std::string uri;
                    uri.reserve(14 + processName.size() + objectPath.size() +
                                interfaceName.size() + strlen(name));
                    uri += "/bus/system/";
                    uri += processName;
                    uri += objectPath;
                    uri += "/";
                    uri += interfaceName;
                    uri += "/";
                    uri += name;

                    nlohmann::json::object_t object;
                    object["name"] = name;
                    object["uri"] = std::move(uri);
                    object["args"] = argsArray;

                    methodsArray.emplace_back(std::move(object));
                }
                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)
                {
                    nlohmann::json::object_t object;
                    object["name"] = name;
                    object["args"] = argsArray;
                    signalsArray.emplace_back(std::move(object));
                }

                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_t 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](const boost::system::error_code& ec2,
                                       sdbusplus::message_t& msg) {
                        if (ec2)
                        {
                            return;
                        }

                        int r = convertDBusToJSON("v", msg, propertyItem);
                        if (r < 0)
                        {
                            BMCWEB_LOG_ERROR("Couldn't convert vector to json");
                        }
                    });
                }
                property = property->NextSiblingElement("property");
            }
        },
            processName, objectPath, "org.freedesktop.DBus.Introspectable",
            "Introspect");
    }
    else
    {
        if (req.method() != boost::beast::http::verb::post)
        {
            asyncResp->res.result(boost::beast::http::status::not_found);
            return;
        }

        nlohmann::json requestDbusData;
        JsonParseResult ret = parseRequestAsJson(req, requestDbusData);
        if (ret == JsonParseResult::BadContentType)
        {
            setErrorResponse(asyncResp->res,
                             boost::beast::http::status::unsupported_media_type,
                             invalidContentType, unsupportedMediaMsg);
            return;
        }
        if (ret != JsonParseResult::Success)
        {
            setErrorResponse(asyncResp->res,
                             boost::beast::http::status::bad_request,
                             noJsonDesc, badReqMsg);
            return;
        }

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

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

        findActionOnInterface(transaction, processName);
    }
}

inline void requestRoutes(App& app)
{
    BMCWEB_ROUTE(app, "/bus/")
        .privileges({{"Login"}})
        .methods(boost::beast::http::verb::get)(
            [](const crow::Request&,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
        nlohmann::json::array_t buses;
        nlohmann::json& bus = buses.emplace_back();
        bus["name"] = "system";
        asyncResp->res.jsonValue["busses"] = std::move(buses);
        asyncResp->res.jsonValue["status"] = "ok";
    });

    BMCWEB_ROUTE(app, "/bus/system/")
        .privileges({{"Login"}})
        .methods(boost::beast::http::verb::get)(
            [](const crow::Request&,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
        auto myCallback = [asyncResp](const boost::system::error_code& ec,
                                      std::vector<std::string>& names) {
            if (ec)
            {
                BMCWEB_LOG_ERROR("Dbus call failed with code {}", ec);
                asyncResp->res.result(
                    boost::beast::http::status::internal_server_error);
            }
            else
            {
                std::ranges::sort(names);
                asyncResp->res.jsonValue["status"] = "ok";
                auto& objectsSub = asyncResp->res.jsonValue["objects"];
                for (const auto& name : names)
                {
                    nlohmann::json::object_t object;
                    object["name"] = name;
                    objectsSub.emplace_back(std::move(object));
                }
            }
        };
        crow::connections::systemBus->async_method_call(
            std::move(myCallback), "org.freedesktop.DBus", "/",
            "org.freedesktop.DBus", "ListNames");
    });

    BMCWEB_ROUTE(app, "/list/")
        .privileges({{"Login"}})
        .methods(boost::beast::http::verb::get)(
            [](const crow::Request&,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
        handleList(asyncResp, "/");
    });

    BMCWEB_ROUTE(app, "/xyz/<path>")
        .privileges({{"Login"}})
        .methods(boost::beast::http::verb::get)(
            [](const crow::Request& req,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
               const std::string& path) {
        std::string objectPath = "/xyz/" + path;
        handleDBusUrl(req, asyncResp, objectPath);
    });

    BMCWEB_ROUTE(app, "/xyz/<path>")
        .privileges({{"ConfigureComponents", "ConfigureManager"}})
        .methods(boost::beast::http::verb::put, boost::beast::http::verb::post,
                 boost::beast::http::verb::delete_)(
            [](const crow::Request& req,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
               const std::string& path) {
        std::string objectPath = "/xyz/" + path;
        handleDBusUrl(req, asyncResp, objectPath);
    });

    BMCWEB_ROUTE(app, "/org/<path>")
        .privileges({{"Login"}})
        .methods(boost::beast::http::verb::get)(
            [](const crow::Request& req,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
               const std::string& path) {
        std::string objectPath = "/org/" + path;
        handleDBusUrl(req, asyncResp, objectPath);
    });

    BMCWEB_ROUTE(app, "/org/<path>")
        .privileges({{"ConfigureComponents", "ConfigureManager"}})
        .methods(boost::beast::http::verb::put, boost::beast::http::verb::post,
                 boost::beast::http::verb::delete_)(
            [](const crow::Request& req,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
               const std::string& path) {
        std::string objectPath = "/org/" + path;
        handleDBusUrl(req, asyncResp, objectPath);
    });

    BMCWEB_ROUTE(app, "/download/dump/<str>/")
        .privileges({{"ConfigureManager"}})
        .methods(boost::beast::http::verb::get)(
            [](const crow::Request&,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
               const std::string& dumpId) {
        if (!validateFilename(dumpId))
        {
            asyncResp->res.result(boost::beast::http::status::bad_request);
            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("{}Not found", loc.string());
            asyncResp->res.result(boost::beast::http::status::not_found);
            return;
        }
        std::filesystem::directory_iterator files(loc);

        for (const auto& file : files)
        {
            if (!asyncResp->res.openFile(file))
            {
                continue;
            }

            asyncResp->res.addHeader(boost::beast::http::field::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
            static std::regex dumpFileRegex("[a-zA-Z0-9\\._]+");
            if (!std::regex_match(dumpFileName, dumpFileRegex))
            {
                BMCWEB_LOG_ERROR("Invalid dump filename {}", dumpFileName);
                asyncResp->res.result(boost::beast::http::status::not_found);
                return;
            }
            std::string contentDispositionParam = "attachment; filename=\"" +
                                                  dumpFileName + "\"";

            asyncResp->res.addHeader(
                boost::beast::http::field::content_disposition,
                contentDispositionParam);

            return;
        }
        asyncResp->res.result(boost::beast::http::status::not_found);
        return;
    });

    BMCWEB_ROUTE(app, "/bus/system/<str>/")
        .privileges({{"Login"}})

        .methods(boost::beast::http::verb::get)(
            [](const crow::Request&,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
               const std::string& connection) {
        introspectObjects(connection, "/", asyncResp);
    });

    BMCWEB_ROUTE(app, "/bus/system/<str>/<path>")
        .privileges({{"ConfigureComponents", "ConfigureManager"}})
        .methods(boost::beast::http::verb::get,
                 boost::beast::http::verb::post)(handleBusSystemPost);
}
} // namespace openbmc_mapper
} // namespace crow
