/*
// 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 "dbus_utility.hpp"
#include "health.hpp"
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "persistent_data.hpp"
#include "query.hpp"
#include "redfish_util.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/boot_time_utils.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/json_utils.hpp"
#include "utils/sw_utils.hpp"
#include "utils/systemd_utils.hpp"
#include "utils/time_utils.hpp"

#include <boost/container/flat_set.hpp>
#include <boost/system/error_code.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/unpack_properties.hpp>
#include <utils/location_utils.hpp>
#include "chassis.hpp"

#include <algorithm>
#include <array>
#include <cstdint>
#include <memory>
#include <sstream>
#include <string_view>
#include <variant>

#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp" // NOLINT
#endif

namespace redfish
{

/**
 * Function reboots the BMC.
 *
 * @param[in] asyncResp - Shared pointer for completing asynchronous calls
 */
inline void
    doBMCGracefulRestart(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    const char* processName = "xyz.openbmc_project.State.BMC";
    const char* objectPath = "/xyz/openbmc_project/state/bmc0";
    const char* interfaceName = "xyz.openbmc_project.State.BMC";
    const std::string& propertyValue =
        "xyz.openbmc_project.State.BMC.Transition.Reboot";
    const char* destProperty = "RequestedBMCTransition";

    // Create the D-Bus variant for D-Bus call.
    dbus::utility::DbusVariantType dbusPropertyValue(propertyValue);

    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [asyncResp](const boost::system::error_code& ec) {
        // Use "Set" method to set the property value.
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "[Set] Bad D-Bus request error: " << ec;
            messages::internalError(asyncResp->res);
            return;
        }

        messages::success(asyncResp->res);
        },
        processName, objectPath, "org.freedesktop.DBus.Properties", "Set",
        interfaceName, destProperty, std::move(dbusPropertyValue));
}

inline void
    doBMCForceRestart(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    const char* processName = "xyz.openbmc_project.State.BMC";
    const char* objectPath = "/xyz/openbmc_project/state/bmc0";
    const char* interfaceName = "xyz.openbmc_project.State.BMC";
    const std::string& propertyValue =
        "xyz.openbmc_project.State.BMC.Transition.HardReboot";
    const char* destProperty = "RequestedBMCTransition";

    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [asyncResp](const boost::system::error_code& ec) {
        // Use "Set" method to set the property value.
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "[Set] Bad D-Bus request error: " << ec;
            messages::internalError(asyncResp->res);
            return;
        }

        messages::success(asyncResp->res);
        },
        processName, objectPath, "org.freedesktop.DBus.Properties", "Set",
        interfaceName, destProperty, dbus::utility::DbusVariantType{propertyValue});
}

inline void handlePostManagerResetAction(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    BMCWEB_LOG_DEBUG << "Post Manager Reset.";

    std::string resetType;

    if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
    {
        return;
    }

    if (resetType == "GracefulRestart")
    {
        BMCWEB_LOG_DEBUG << "Proceeding with " << resetType;
        doBMCGracefulRestart(asyncResp);
        return;
    }
    if (resetType == "ForceRestart")
    {
        BMCWEB_LOG_DEBUG << "Proceeding with " << resetType;
        doBMCForceRestart(asyncResp);
        return;
    }
    if (resetType == "TrayPowerCycle")
    {
        BMCWEB_LOG_DEBUG << "Proceeding with " << resetType;
        // We don't support delay powercycle for now. If S4 wants to use it in
        // the future, we will add it.
        std::optional<int> delayTimeSecs = std::nullopt;
        doChassisPowerCycle(asyncResp, delayTimeSecs);
        return;
    }

    BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: " << resetType;
    messages::actionParameterNotSupported(asyncResp->res, resetType,
                                          "ResetType");
}

/**
 * ManagerResetAction class supports the POST method for the Reset (reboot)
 * action.
 */
inline void requestRoutesManagerResetAction(App& app)
{
    /**
     * Function handles POST method request.
     * Analyzes POST body before sending Reset (Reboot) request data to D-Bus.
     * OpenBMC supports ResetType "GracefulRestart" and "ForceRestart".
     */

    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Actions/Manager.Reset/")
        .privileges(redfish::privileges::postManager)
        .methods(boost::beast::http::verb::post)(
            std::bind_front(handlePostManagerResetAction, std::ref(app)));
}

inline void handlePostManagerResetToDefaultsAction(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    BMCWEB_LOG_DEBUG << "Post ResetToDefaults.";

    std::string resetType;

    if (!json_util::readJsonAction(req, asyncResp->res, "ResetToDefaultsType",
                                   resetType))
    {
        BMCWEB_LOG_DEBUG << "Missing property ResetToDefaultsType.";

        messages::actionParameterMissing(asyncResp->res, "ResetToDefaults",
                                         "ResetToDefaultsType");
        return;
    }

    if (resetType != "ResetAll")
    {
        BMCWEB_LOG_DEBUG << "Invalid property value for ResetToDefaultsType: "
                         << resetType;
        messages::actionParameterNotSupported(asyncResp->res, resetType,
                                              "ResetToDefaultsType");
        return;
    }

    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [asyncResp](const boost::system::error_code& ec) {
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "Failed to ResetToDefaults: " << ec;
            messages::internalError(asyncResp->res);
            return;
        }
        // Factory Reset doesn't actually happen until a reboot
        // Can't erase what the BMC is running on
        doBMCGracefulRestart(asyncResp);
    }, "xyz.openbmc_project.Software.BMC.Updater",
        "/xyz/openbmc_project/software",
        "xyz.openbmc_project.Common.FactoryReset", "Reset");
}
/**
 * ManagerResetToDefaultsAction class supports POST method for factory reset
 * action.
 */
inline void requestRoutesManagerResetToDefaultsAction(App& app)
{

    /**
     * Function handles ResetToDefaults POST method request.
     *
     * Analyzes POST body message and factory resets BMC by calling
     * BMC code updater factory reset followed by a BMC reboot.
     *
     * BMC code updater factory reset wipes the whole BMC read-write
     * filesystem which includes things like the network settings.
     *
     * OpenBMC only supports ResetToDefaultsType "ResetAll".
     */

    BMCWEB_ROUTE(app,
                 "/redfish/v1/Managers/bmc/Actions/Manager.ResetToDefaults/")
        .privileges(redfish::privileges::postManager)
        .methods(boost::beast::http::verb::post)(std::bind_front(
            handlePostManagerResetToDefaultsAction, std::ref(app)));
}

inline void handleManagerResetActionInfo(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/Managers/bmc/ResetActionInfo";
    asyncResp->res.jsonValue["Name"] = "Reset Action Info";
    asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
    nlohmann::json::object_t parameter;
    parameter["Name"] = "ResetType";
    parameter["Required"] = true;
    parameter["DataType"] = "String";

    nlohmann::json::array_t allowableValues;
    allowableValues.emplace_back("GracefulRestart");
    allowableValues.emplace_back("ForceRestart");
    allowableValues.emplace_back("TrayPowerCycle");
    parameter["AllowableValues"] = std::move(allowableValues);

    nlohmann::json::array_t parameters;
    parameters.emplace_back(std::move(parameter));

    asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
}

/**
 * ManagerResetActionInfo derived class for delivering Manager
 * ResetType AllowableValues using ResetInfo schema.
 */
inline void requestRoutesManagerResetActionInfo(App& app)
{
    /**
     * Functions triggers appropriate requests on DBus
     */

    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/ResetActionInfo/")
        .privileges(redfish::privileges::getActionInfo)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleManagerResetActionInfo, std::ref(app)));
}

inline void handlePostManagerFanModeChangeAction(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    std::string fanMode;
    if (!json_util::readJsonAction(req, asyncResp->res, "FanMode", fanMode))
    {
        messages::actionParameterUnknown(asyncResp->res, "FanMode", "");
        return;
    }

    bool munualMode = false;
    if (fanMode == "Manual")
    {
        munualMode = true;
    }
    else if (fanMode == "Auto")
    {
        munualMode = false;
    }
    else
    {
        messages::actionParameterValueFormatError(asyncResp->res, "Manual",
                                                  "Auto", "");
        return;
    }
    std::array<std::string_view, 1> interfaces{
        "xyz.openbmc_project.Control.Mode"};

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTree(
        "/xyz/openbmc_project/settings/fanctrl", 1, interfaces, requestContext,
        [asyncResp{asyncResp}, munualMode](
            const boost::system::error_code& ec,
            const std::vector<std::pair<
                std::string,
                std::vector<std::pair<std::string, std::vector<std::string>>>>>&
                subtree) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "fanctrl GetSubTree failed "
                             << " ec = ( " << ec << " )\n";
            messages::internalError(asyncResp->res);
            return;
        }

        for (const auto& object : subtree)
        {
            auto iter = object.first.rfind('/');
            if ((iter != std::string::npos) && (iter < object.first.size()))
            {
                std::string objName = object.first.substr(iter + 1);
                managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
                    asyncResp->strand_,
                    [asyncResp, objName,
                     munualMode](const boost::system::error_code ec2) {
                    if (ec2)
                    {
                        BMCWEB_LOG_ERROR << "Updated the Mode failed "
                                         << objName << ": " << munualMode
                                         << " ec = ( " << ec2 << " )\n";
                        messages::internalError(asyncResp->res);
                        return;
                    }
                },
                    "xyz.openbmc_project.State.FanCtrl",
                    "/xyz/openbmc_project/settings/fanctrl/" + objName,
                    "org.freedesktop.DBus.Properties", "Set",
                    "xyz.openbmc_project.Control.Mode", "Manual",
                    dbus::utility::DbusVariantType{munualMode});
                BMCWEB_LOG_DEBUG << "Updated the Mode success " << objName
                                 << ": " << munualMode;
            }
        }
        messages::success(asyncResp->res);
    });
}

/**
 * ManagerFanModeChangeAction class supports POST method for Fan Mode Change
 * action.
 */
inline void requestRoutesManagerFanModeChangeAction(App& app)
{

    /**
     * Function handles FanMode POST method request.
     *
     * OpenBMC only supports FanMode "Manual" or "Auto".
     */

    BMCWEB_ROUTE(app,
                 "/redfish/v1/Managers/bmc/Actions/Manager.FanMode.Change/")
        .privileges(redfish::privileges::postManager)
        .methods(boost::beast::http::verb::post)(std::bind_front(
            handlePostManagerFanModeChangeAction, std::ref(app)));
}

inline void handleGetManagerFanModeChangeActionInfo(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    asyncResp->res.jsonValue = {
        {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
        {"@odata.id", "/redfish/v1/Managers/bmc/FanMode.Change.ActionInfo"},
        {"Name", "FanMode Change Action Info"},
        {"Id", "FanMode.Change.ActionInfo"},
        {"Parameters",
         {{{"Name", "FanMode"},
           {"Required", true},
           {"DataType", "String"},
           {"AllowableValues", {"Manual", "Auto"}}}}}};
}

/**
 * ManagerFanModeChangeActionInfo derived class for delivering Manager
 * FanMode AllowableValues using FanModeInfo schema.
 */
inline void requestRoutesManagerFanModeChangeActionInfo(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/FanMode.Change.ActionInfo/")
        .privileges(redfish::privileges::getActionInfo)
        .methods(boost::beast::http::verb::get)(std::bind_front(
            handleGetManagerFanModeChangeActionInfo, std::ref(app)));
}

inline void
    updateZoneLeaderInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                         const std::string& zoneIndex, const std::string& name,
                         const std::string& leader,
                         const managedStore::ManagedObjectStoreContext& context)
{
    managedStore::GetManagedObjectStore()->getAllProperties(
        "xyz.openbmc_project.State.FanCtrl",
        crow::utility::urlFromPieces("xyz", "openbmc_project", "settings",
                                     "fanctrl", "zone" + zoneIndex, leader)
            .buffer(),
        "xyz.openbmc_project.Debug.Pid.ThermalPower", context,
        [asyncResp, zoneIndex, name,
         leader](const boost::system::error_code ec,
                 const ::dbus::utility::DBusPropertiesMap& leaderData) {
        if (ec)
        {
            BMCWEB_LOG_WARNING << "Get the Fan Zone Leader failed " << leader
                               << " ec = ( " << ec << " )\n";
            return;
        }

        for (const auto& data : leaderData)
        {
            std::string propertyName;
            if (data.first == "Leader")
            {
                propertyName = "Sensor";
            }
            else
            {
                propertyName = data.first;
            }

            if (const std::string* strPtr =
                    std::get_if<std::string>(&data.second))
            {
                asyncResp->res.jsonValue["Oem"]["OpenBmc"]["Fan"]["FanZones"]
                                        [name]["Leader"][propertyName] =
                    *strPtr;
            }
            else if (const double* doublePtr =
                         std::get_if<double>(&data.second))
            {
                asyncResp->res.jsonValue["Oem"]["OpenBmc"]["Fan"]["FanZones"]
                                        [name]["Leader"][propertyName] =
                    *doublePtr;
            }
            else
            {
                BMCWEB_LOG_WARNING << "Get the Fan Zone Debug info "
                                   << "failed " << leader << ", "
                                   << propertyName << " ec = ( " << ec
                                   << " )\n";
                asyncResp->res.jsonValue["Oem"]["OpenBmc"]["Fan"]["FanZones"]
                                        [name]["Leader"][propertyName] = "n/a";
                return;
            }
        }
    });
}

static constexpr const char* objectManagerIface =
    "org.freedesktop.DBus.ObjectManager";
static constexpr const char* pidConfigurationIface =
    "xyz.openbmc_project.Configuration.Pid";
static constexpr const char* pidZoneConfigurationIface =
    "xyz.openbmc_project.Configuration.Pid.Zone";
static constexpr const char* stepwiseConfigurationIface =
    "xyz.openbmc_project.Configuration.Stepwise";
static constexpr const char* thermalModeIface =
    "xyz.openbmc_project.Control.ThermalMode";

inline void
    asyncPopulatePid(const std::string& connection, const std::string& path,
                     const std::string& currentProfile,
                     const std::vector<std::string>& supportedProfiles,
                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    managedStore::ManagedObjectStoreContext context(asyncResp);
    managedStore::GetManagedObjectStore()->getManagedObjectsWithContext(
        connection, path, context,
        [asyncResp, currentProfile, supportedProfiles, context](
            const boost::system::error_code& ec,
            const dbus::utility::ManagedObjectType& managedObj) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "asyncPopulatePid: " << ec;
            asyncResp->res.jsonValue.clear();
            messages::internalError(asyncResp->res);
            return;
        }
        nlohmann::json& configRoot =
            asyncResp->res.jsonValue["Oem"]["OpenBmc"]["Fan"];
        nlohmann::json& fans = configRoot["FanControllers"];
        fans["@odata.type"] = "#OemManager.FanControllers";
        fans["@odata.id"] =
            "/redfish/v1/Managers/bmc#/Oem/OpenBmc/Fan/FanControllers";

        nlohmann::json& pids = configRoot["PidControllers"];
        pids["@odata.type"] = "#OemManager.PidControllers";
        pids["@odata.id"] =
            "/redfish/v1/Managers/bmc#/Oem/OpenBmc/Fan/PidControllers";

        nlohmann::json& stepwise = configRoot["StepwiseControllers"];
        stepwise["@odata.type"] = "#OemManager.StepwiseControllers";
        stepwise["@odata.id"] =
            "/redfish/v1/Managers/bmc#/Oem/OpenBmc/Fan/StepwiseControllers";

        nlohmann::json& zones = configRoot["FanZones"];
        zones["@odata.id"] =
            "/redfish/v1/Managers/bmc#/Oem/OpenBmc/Fan/FanZones";
        zones["@odata.type"] = "#OemManager.FanZones";
        configRoot["@odata.id"] = "/redfish/v1/Managers/bmc#/Oem/OpenBmc/Fan";
        configRoot["@odata.type"] = "#OemManager.Fan";
        configRoot["Profile@Redfish.AllowableValues"] = supportedProfiles;

        if (!currentProfile.empty())
        {
            configRoot["Profile"] = currentProfile;
        }
        BMCWEB_LOG_ERROR << "profile = " << currentProfile << " !";

        for (const auto& pathPair : managedObj)
        {
            for (const auto& intfPair : pathPair.second)
            {
                if (intfPair.first != pidConfigurationIface &&
                    intfPair.first != pidZoneConfigurationIface &&
                    intfPair.first != stepwiseConfigurationIface)
                {
                    continue;
                }

                std::string name;

                for (const std::pair<std::string,
                                     dbus::utility::DbusVariantType>& propPair :
                     intfPair.second)
                {
                    if (propPair.first == "Name")
                    {
                        const std::string* namePtr =
                            std::get_if<std::string>(&propPair.second);
                        if (namePtr == nullptr)
                        {
                            BMCWEB_LOG_ERROR << "Pid Name Field illegal";
                            messages::internalError(asyncResp->res);
                            return;
                        }
                        name = *namePtr;
                        dbus::utility::escapePathForDbus(name);
                    }
                    else if (propPair.first == "Profiles")
                    {
                        const std::vector<std::string>* profiles =
                            std::get_if<std::vector<std::string>>(
                                &propPair.second);
                        if (profiles == nullptr)
                        {
                            BMCWEB_LOG_ERROR << "Pid Profiles Field illegal";
                            messages::internalError(asyncResp->res);
                            return;
                        }
                        if (std::find(profiles->begin(), profiles->end(),
                                      currentProfile) == profiles->end())
                        {
                            BMCWEB_LOG_INFO
                                << name << " not supported in current profile";
                            continue;
                        }
                    }
                }
                nlohmann::json* config = nullptr;
                const std::string* classPtr = nullptr;
                const double* zoneIndexPtr = nullptr;
                const double* zoneMinThermalOutputPtr = nullptr;

                for (const std::pair<std::string,
                                     dbus::utility::DbusVariantType>& propPair :
                     intfPair.second)
                {
                    if (propPair.first == "Class")
                    {
                        classPtr = std::get_if<std::string>(&propPair.second);
                    }
                    else if (propPair.first == "ZoneIndex")
                    {
                        zoneIndexPtr = std::get_if<double>(&propPair.second);
                    }
                    else if (propPair.first == "MinThermalOutput")
                    {
                        zoneMinThermalOutputPtr =
                            std::get_if<double>(&propPair.second);
                    }
                }

                boost::urls::url url = crow::utility::urlFromPieces(
                    "redfish", "v1", "Managers", "bmc");
                if (intfPair.first == pidZoneConfigurationIface)
                {
                    std::string chassis;
                    if (!dbus::utility::getNthStringFromPath(pathPair.first.str,
                                                             5, chassis))
                    {
                        chassis = "#IllegalValue";
                    }
                    nlohmann::json& zone = zones[name];
                    zone["Chassis"]["@odata.id"] = crow::utility::urlFromPieces(
                        "redfish", "v1", "Chassis", chassis);
                    url.set_fragment(
                        ("/Oem/OpenBmc/Fan/FanZones"_json_pointer / name)
                            .to_string());
                    zone["@odata.id"] = url;
                    zone["@odata.type"] = "#OemManager.FanZone";
                    config = &zone;

                    // Add FanMode status
                    std::string zoneIndex;
                    if (zoneIndexPtr == nullptr)
                    {
                        // ZoneIndex field is optional. If not given, attempt
                        // to synthesize it out of the name string.
                        // The idea of a zone index is legacy, for IPMI
                        // OEM commands, and has no purpose under Redfish.
                        // Long term, need to refactor to address all thermal
                        // zones by name, not by index number.
                        // This requires work in bmcweb, entity-manager,
                        // phosphor-dbus-interfaces, phosphor-pid-control.
                        auto len = name.size();
                        auto pos = len;
                        while (pos > 0)
                        {
                            // Take suffix from right to left
                            --pos;
                            char digit = name[pos];
                            if (digit < '0' || digit > '9')
                            {
                                // Avoid taking anything non-numeric
                                ++pos;
                                break;
                            }
                        }
                        if (pos < len)
                        {
                            // Extract the numeric suffix out of the zone name
                            zoneIndex = name.substr(pos);
                        }
                        if (zoneIndex.empty())
                        {
                            BMCWEB_LOG_ERROR << "Pid Zone Index Field illegal";
                            messages::internalError(asyncResp->res);
                            return;
                        }
                    }
                    else
                    {
                        zoneIndex =
                            std::to_string(static_cast<int>(*(zoneIndexPtr)));
                    }

                    if (name.starts_with("Zone") && !zoneIndex.empty())
                    {
                        dbus_utils::getProperty<bool>(
                            "xyz.openbmc_project.State.FanCtrl",
                            "/xyz/openbmc_project/settings/fanctrl/zone" +
                                zoneIndex,
                            "xyz.openbmc_project.Control.Mode", "Manual", context,
                            [asyncResp, name](const boost::system::error_code ec2,
                                              bool manualEnabled) {
                            if (ec2)
                            {
                                BMCWEB_LOG_WARNING << "Get the FanMode failed "
                                                 << name << " ec = ( " << ec2
                                                 << " )\n";
                                // If phosphor-pid-control service not running,
                                // indicate Disabled instead of Auto/Manual,
                                // but otherwise return successful.
                                asyncResp->res
                                .jsonValue["Oem"]["OpenBmc"]["Fan"]
                                          ["FanZones"][name]["FanMode"] =
                                "Disabled";
                                return;
                            }
                            if (manualEnabled)
                            {
                                asyncResp->res
                                    .jsonValue["Oem"]["OpenBmc"]["Fan"]
                                              ["FanZones"][name]["FanMode"] =
                                    "Manual";
                            }
                            else
                            {
                                asyncResp->res
                                    .jsonValue["Oem"]["OpenBmc"]["Fan"]
                                              ["FanZones"][name]["FanMode"] =
                                    "Auto";
                            }
                            });

                        dbus_utils::getProperty<bool>(
                            "xyz.openbmc_project.State.FanCtrl",
                            "/xyz/openbmc_project/settings/fanctrl/zone" +
                                zoneIndex,
                            "xyz.openbmc_project.Control.Mode", "FailSafe", context,
                            [asyncResp, name](const boost::system::error_code ec2,
                                              bool failsafeEnabled) {
                            if (ec2)
                            {
                                BMCWEB_LOG_WARNING << "Get the FailSafe failed "
                                                 << name << " ec = ( " << ec2
                                                 << " )\n";
                                // If phosphor-pid-control service not running,
                                // indicate Disabled instead of Normal/Active,
                                // but otherwise return successful.
                                asyncResp->res
                                .jsonValue["Oem"]["OpenBmc"]["Fan"]
                                          ["FanZones"][name]["FailSafe"] =
                                "Disabled";
                                return;
                            }
                            if (failsafeEnabled)
                            {
                                asyncResp->res
                                    .jsonValue["Oem"]["OpenBmc"]["Fan"]
                                              ["FanZones"][name]["FailSafe"] =
                                    "Active";
                            }
                            else
                            {
                                asyncResp->res
                                    .jsonValue["Oem"]["OpenBmc"]["Fan"]
                                              ["FanZones"][name]["FailSafe"] =
                                    "Normal";
                            }
                            });

                        dbus_utils::getProperty<std::string>(
                            "xyz.openbmc_project.State.FanCtrl",
                            "/xyz/openbmc_project/settings/fanctrl/zone" +
                                zoneIndex,
                            "xyz.openbmc_project.Debug.Pid.Zone", "Leader",
                            context,
                            [asyncResp, zoneIndex, zoneMinThermalOutputPtr,
                             name, context,
                             url{std::move(url)}](const boost::system::error_code ec2,
                                  const std::string& leader) {
                            if (ec2)
                            {
                                BMCWEB_LOG_WARNING << "Get the Fan Zone failed "
                                                 << name << " ec = ( " << ec2
                                                 << " )\n";
                                // If phosphor-pid-control service not running,
                                // supply no further information,
                                // but otherwise return successful.
                                return;
                            }

                            if (zoneMinThermalOutputPtr == nullptr)
                            {
                                BMCWEB_LOG_ERROR
                                    << "Pid Zone MinThermalOutput Field illegal";
                                messages::internalError(asyncResp->res);
                                return;
                            }

                            boost::urls::url leaderUrl = url;
                            leaderUrl.set_fragment(
                                ("/Oem/OpenBmc/Fan/FanZones"_json_pointer /
                                 name / "Leader")
                                    .to_string());

                            asyncResp->res
                                .jsonValue["Oem"]["OpenBmc"]["Fan"]["FanZones"]
                                          [name]["Leader"]["@odata.id"] =
                                std::move(leaderUrl);

                            if (leader == "Minimum")
                            {
                                asyncResp->res
                                    .jsonValue["Oem"]["OpenBmc"]["Fan"]
                                              ["FanZones"][name]["Leader"]
                                              ["Sensor"] = leader;

                                asyncResp->res
                                    .jsonValue["Oem"]["OpenBmc"]["Fan"]
                                              ["FanZones"][name]["Leader"]
                                              ["Output"] =
                                    *zoneMinThermalOutputPtr;
                            }
                            else
                            {
                                updateZoneLeaderInfo(asyncResp, zoneIndex, name,
                                                     leader, context);
                            }
                            });
                    }
                }

                else if (intfPair.first == stepwiseConfigurationIface)
                {
                    if (classPtr == nullptr)
                    {
                        BMCWEB_LOG_ERROR << "Pid Class Field illegal";
                        messages::internalError(asyncResp->res);
                        return;
                    }

                    nlohmann::json& controller = stepwise[name];
                    config = &controller;
                    url.set_fragment(
                        ("/Oem/OpenBmc/Fan/StepwiseControllers"_json_pointer /
                         name)
                            .to_string());
                    controller["@odata.id"] = std::move(url);
                    controller["@odata.type"] =
                        "#OemManager.StepwiseController";

                    controller["Direction"] = *classPtr;
                }

                // pid and fans are off the same configuration
                else if (intfPair.first == pidConfigurationIface)
                {

                    if (classPtr == nullptr)
                    {
                        BMCWEB_LOG_ERROR << "Pid Class Field illegal";
                        messages::internalError(asyncResp->res);
                        return;
                    }
                    bool isFan = *classPtr == "fan";
                    nlohmann::json& element = isFan ? fans[name] : pids[name];
                    config = &element;
                    if (isFan)
                    {
                        url.set_fragment(
                            ("/Oem/OpenBmc/Fan/FanControllers"_json_pointer /
                             name)
                                .to_string());
                        element["@odata.id"] = std::move(url);
                        element["@odata.type"] = "#OemManager.FanController";
                    }
                    else
                    {
                        url.set_fragment(
                            ("/Oem/OpenBmc/Fan/PidControllers"_json_pointer /
                             name)
                                .to_string());
                        element["@odata.id"] = std::move(url);
                        element["@odata.type"] = "#OemManager.PidController";
                    }
                }
                else
                {
                    BMCWEB_LOG_ERROR << "Unexpected configuration";
                    messages::internalError(asyncResp->res);
                    return;
                }

                // used for making maps out of 2 vectors
                const std::vector<double>* keys = nullptr;
                const std::vector<double>* values = nullptr;

                for (const auto& propertyPair : intfPair.second)
                {
                    if (propertyPair.first == "Type" ||
                        propertyPair.first == "Class" ||
                        propertyPair.first == "Name")
                    {
                        continue;
                    }

                    // zones
                    if (intfPair.first == pidZoneConfigurationIface)
                    {
                        const double* ptr =
                            std::get_if<double>(&propertyPair.second);
                        if (ptr == nullptr)
                        {
                            BMCWEB_LOG_ERROR << "Field Illegal "
                                             << propertyPair.first;
                            messages::internalError(asyncResp->res);
                            return;
                        }
                        (*config)[propertyPair.first] = *ptr;
                    }

                    if (intfPair.first == stepwiseConfigurationIface)
                    {
                        if (propertyPair.first == "Reading" ||
                            propertyPair.first == "Output")
                        {
                            const std::vector<double>* ptr =
                                std::get_if<std::vector<double>>(
                                    &propertyPair.second);

                            if (ptr == nullptr)
                            {
                                BMCWEB_LOG_ERROR << "Field Illegal "
                                                 << propertyPair.first;
                                messages::internalError(asyncResp->res);
                                return;
                            }

                            if (propertyPair.first == "Reading")
                            {
                                keys = ptr;
                            }
                            else
                            {
                                values = ptr;
                            }
                            if (keys != nullptr && values != nullptr)
                            {
                                if (keys->size() != values->size())
                                {
                                    BMCWEB_LOG_ERROR
                                        << "Reading and Output size don't match ";
                                    messages::internalError(asyncResp->res);
                                    return;
                                }
                                nlohmann::json& steps = (*config)["Steps"];
                                steps = nlohmann::json::array();
                                for (size_t ii = 0; ii < keys->size(); ii++)
                                {
                                    nlohmann::json::object_t step;
                                    step["Target"] = (*keys)[ii];
                                    step["Output"] = (*values)[ii];
                                    steps.emplace_back(std::move(step));
                                }
                            }
                        }
                        if (propertyPair.first == "NegativeHysteresis" ||
                            propertyPair.first == "PositiveHysteresis")
                        {
                            const double* ptr =
                                std::get_if<double>(&propertyPair.second);
                            if (ptr == nullptr)
                            {
                                BMCWEB_LOG_ERROR << "Field Illegal "
                                                 << propertyPair.first;
                                messages::internalError(asyncResp->res);
                                return;
                            }
                            (*config)[propertyPair.first] = *ptr;
                        }
                    }

                    // pid and fans are off the same configuration
                    if (intfPair.first == pidConfigurationIface ||
                        intfPair.first == stepwiseConfigurationIface)
                    {

                        if (propertyPair.first == "Zones")
                        {
                            const std::vector<std::string>* inputs =
                                std::get_if<std::vector<std::string>>(
                                    &propertyPair.second);

                            if (inputs == nullptr)
                            {
                                BMCWEB_LOG_ERROR << "Zones Pid Field Illegal";
                                messages::internalError(asyncResp->res);
                                return;
                            }
                            auto& data = (*config)[propertyPair.first];
                            data = nlohmann::json::array();
                            for (std::string itemCopy : *inputs)
                            {
                                dbus::utility::escapePathForDbus(itemCopy);
                                nlohmann::json::object_t input;
                                boost::urls::url managerUrl =
                                    crow::utility::urlFromPieces(
                                        "redfish", "v1", "Managers", "bmc");
                                managerUrl.set_fragment(
                                    ("/Oem/OpenBmc/Fan/FanZones"_json_pointer /
                                     itemCopy)
                                        .to_string());
                                input["@odata.id"] = std::move(managerUrl);
                                data.emplace_back(std::move(input));
                            }
                        }
                        // todo(james): may never happen, but this
                        // assumes configuration data referenced in the
                        // PID config is provided by the same daemon, we
                        // could add another loop to cover all cases,
                        // but I'm okay kicking this can down the road a
                        // bit

                        else if (propertyPair.first == "Inputs" ||
                                 propertyPair.first == "Outputs")
                        {
                            auto& data = (*config)[propertyPair.first];
                            const std::vector<std::string>* inputs =
                                std::get_if<std::vector<std::string>>(
                                    &propertyPair.second);

                            if (inputs == nullptr)
                            {
                                BMCWEB_LOG_ERROR << "Field Illegal "
                                                 << propertyPair.first;
                                messages::internalError(asyncResp->res);
                                return;
                            }
                            data = *inputs;
                        }
                        else if (propertyPair.first == "SetPointOffset")
                        {
                            const std::string* ptr =
                                std::get_if<std::string>(&propertyPair.second);

                            if (ptr == nullptr)
                            {
                                BMCWEB_LOG_ERROR << "Field Illegal "
                                                 << propertyPair.first;
                                messages::internalError(asyncResp->res);
                                return;
                            }
                            // translate from dbus to redfish
                            if (*ptr == "WarningHigh")
                            {
                                (*config)["SetPointOffset"] =
                                    "UpperThresholdNonCritical";
                            }
                            else if (*ptr == "WarningLow")
                            {
                                (*config)["SetPointOffset"] =
                                    "LowerThresholdNonCritical";
                            }
                            else if (*ptr == "CriticalHigh")
                            {
                                (*config)["SetPointOffset"] =
                                    "UpperThresholdCritical";
                            }
                            else if (*ptr == "CriticalLow")
                            {
                                (*config)["SetPointOffset"] =
                                    "LowerThresholdCritical";
                            }
                            else
                            {
                                BMCWEB_LOG_ERROR << "Value Illegal " << *ptr;
                                messages::internalError(asyncResp->res);
                                return;
                            }
                        }
                        // doubles
                        else if (propertyPair.first == "FFGainCoefficient" ||
                                 propertyPair.first == "FFOffCoefficient" ||
                                 propertyPair.first == "ICoefficient" ||
                                 propertyPair.first == "ILimitMax" ||
                                 propertyPair.first == "ILimitMin" ||
                                 propertyPair.first == "PositiveHysteresis" ||
                                 propertyPair.first == "NegativeHysteresis" ||
                                 propertyPair.first == "OutLimitMax" ||
                                 propertyPair.first == "OutLimitMin" ||
                                 propertyPair.first == "PCoefficient" ||
                                 propertyPair.first == "SetPoint" ||
                                 propertyPair.first == "SlewNeg" ||
                                 propertyPair.first == "SlewPos")
                        {
                            const double* ptr =
                                std::get_if<double>(&propertyPair.second);
                            if (ptr == nullptr)
                            {
                                BMCWEB_LOG_ERROR << "Field Illegal "
                                                 << propertyPair.first;
                                messages::internalError(asyncResp->res);
                                return;
                            }
                            (*config)[propertyPair.first] = *ptr;
                        }
                    }
                }
            }
        }
        });
}

enum class CreatePIDRet : std::uint8_t
{
    fail,
    del,
    patch
};

inline bool
    getZonesFromJsonReq(const std::shared_ptr<bmcweb::AsyncResp>& response,
                        std::vector<nlohmann::json>& config,
                        std::vector<std::string>& zones)
{
    if (config.empty())
    {
        BMCWEB_LOG_ERROR << "Empty Zones";
        messages::propertyValueFormatError(response->res, "[]", "Zones");
        return false;
    }
    for (auto& odata : config)
    {
        std::string path;
        if (!redfish::json_util::readJson(odata, response->res, "@odata.id",
                                          path))
        {
            return false;
        }
        std::string input;

        // 8 below comes from
        // /redfish/v1/Managers/bmc#/Oem/OpenBmc/Fan/FanZones/Left
        //     0    1     2      3    4    5      6     7      8
        if (!dbus::utility::getNthStringFromPath(path, 8, input))
        {
            BMCWEB_LOG_ERROR << "Got invalid path " << path;
            BMCWEB_LOG_ERROR << "Illegal Type Zones";
            messages::propertyValueFormatError(response->res, odata.dump(),
                                               "Zones");
            return false;
        }
        std::replace(input.begin(), input.end(), '_', ' ');
        zones.emplace_back(std::move(input));
    }
    return true;
}

inline const dbus::utility::ManagedObjectType::value_type*
    findChassis(const dbus::utility::ManagedObjectType& managedObj,
                const std::string& value, std::string& chassis)
{
    BMCWEB_LOG_DEBUG << "Find Chassis: " << value << "\n";

    std::string escaped = value;
    std::replace(escaped.begin(), escaped.end(), ' ', '_');
    escaped = "/" + escaped;
    auto it = std::find_if(managedObj.begin(), managedObj.end(),
                           [&escaped](const auto& obj) {
        if (boost::algorithm::ends_with(obj.first.str, escaped))
        {
            BMCWEB_LOG_DEBUG << "Matched " << obj.first.str << "\n";
            return true;
        }
        return false;
    });

    if (it == managedObj.end())
    {
        return nullptr;
    }
    // 5 comes from <chassis-name> being the 5th element
    // /xyz/openbmc_project/inventory/system/chassis/<chassis-name>
    if (dbus::utility::getNthStringFromPath(it->first.str, 5, chassis))
    {
        return &(*it);
    }

    return nullptr;
}

inline CreatePIDRet createPidInterface(
    const std::shared_ptr<bmcweb::AsyncResp>& response, const std::string& type,
    const nlohmann::json::iterator& it, const std::string& path,
    const dbus::utility::ManagedObjectType& managedObj, bool createNewObject,
    dbus::utility::DBusPropertiesMap& output, std::string& chassis,
    const std::string& profile)
{

    // common deleter
    if (it.value() == nullptr)
    {
        std::string iface;
        if (type == "PidControllers" || type == "FanControllers")
        {
            iface = pidConfigurationIface;
        }
        else if (type == "FanZones")
        {
            iface = pidZoneConfigurationIface;
        }
        else if (type == "StepwiseControllers")
        {
            iface = stepwiseConfigurationIface;
        }
        else
        {
            BMCWEB_LOG_ERROR << "Illegal Type " << type;
            messages::propertyUnknown(response->res, type);
            return CreatePIDRet::fail;
        }

        BMCWEB_LOG_DEBUG << "del " << path << " " << iface << "\n";
        // delete interface
        managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
            response->strand_,
            [response, path](const boost::system::error_code& ec) {
            if (ec)
            {
                BMCWEB_LOG_ERROR << "Error patching " << path << ": " << ec;
                messages::internalError(response->res);
                return;
            }
            messages::success(response->res);
            },
            "xyz.openbmc_project.EntityManager", path, iface, "Delete");
        return CreatePIDRet::del;
    }

    const dbus::utility::ManagedObjectType::value_type* managedItem = nullptr;
    if (!createNewObject)
    {
        // if we aren't creating a new object, we should be able to find it on
        // d-bus
        managedItem = findChassis(managedObj, it.key(), chassis);
        if (managedItem == nullptr)
        {
            BMCWEB_LOG_ERROR << "Failed to get chassis from config patch";
            messages::invalidObject(response->res,
                                    crow::utility::urlFromPieces(
                                        "redfish", "v1", "Chassis", chassis));
            return CreatePIDRet::fail;
        }
    }

    if (!profile.empty() &&
        (type == "PidControllers" || type == "FanControllers" ||
         type == "StepwiseControllers"))
    {
        if (managedItem == nullptr)
        {
            output.emplace_back("Profiles", std::vector<std::string>{profile});
        }
        else
        {
            std::string interface;
            if (type == "StepwiseControllers")
            {
                interface = stepwiseConfigurationIface;
            }
            else
            {
                interface = pidConfigurationIface;
            }
            bool ifaceFound = false;
            for (const auto& iface : managedItem->second)
            {
                if (iface.first == interface)
                {
                    ifaceFound = true;
                    for (const auto& prop : iface.second)
                    {
                        if (prop.first == "Profiles")
                        {
                            const std::vector<std::string>* curProfiles =
                                std::get_if<std::vector<std::string>>(
                                    &(prop.second));
                            if (curProfiles == nullptr)
                            {
                                BMCWEB_LOG_ERROR
                                    << "Illegal profiles in managed object";
                                messages::internalError(response->res);
                                return CreatePIDRet::fail;
                            }
                            if (std::find(curProfiles->begin(),
                                          curProfiles->end(),
                                          profile) == curProfiles->end())
                            {
                                std::vector<std::string> newProfiles =
                                    *curProfiles;
                                newProfiles.emplace_back(profile);
                                output.emplace_back("Profiles", newProfiles);
                            }
                        }
                    }
                }
            }

            if (!ifaceFound)
            {
                BMCWEB_LOG_ERROR
                    << "Failed to find interface in managed object";
                messages::internalError(response->res);
                return CreatePIDRet::fail;
            }
        }
    }

    if (type == "PidControllers" || type == "FanControllers")
    {
        if (createNewObject)
        {
            output.emplace_back("Class",
                                type == "PidControllers" ? "temp" : "fan");
            output.emplace_back("Type", "Pid");
        }

        std::optional<std::vector<nlohmann::json>> zones;
        std::optional<std::vector<std::string>> inputs;
        std::optional<std::vector<std::string>> outputs;
        std::map<std::string, std::optional<double>> doubles;
        std::optional<std::string> setpointOffset;
        if (!redfish::json_util::readJson(
                it.value(), response->res, "Inputs", inputs, "Outputs", outputs,
                "Zones", zones, "FFGainCoefficient",
                doubles["FFGainCoefficient"], "FFOffCoefficient",
                doubles["FFOffCoefficient"], "ICoefficient",
                doubles["ICoefficient"], "ILimitMax", doubles["ILimitMax"],
                "ILimitMin", doubles["ILimitMin"], "OutLimitMax",
                doubles["OutLimitMax"], "OutLimitMin", doubles["OutLimitMin"],
                "PCoefficient", doubles["PCoefficient"], "SetPoint",
                doubles["SetPoint"], "SetPointOffset", setpointOffset,
                "SlewNeg", doubles["SlewNeg"], "SlewPos", doubles["SlewPos"],
                "PositiveHysteresis", doubles["PositiveHysteresis"],
                "NegativeHysteresis", doubles["NegativeHysteresis"]))
        {
            return CreatePIDRet::fail;
        }
        if (zones)
        {
            std::vector<std::string> zonesStr;
            if (!getZonesFromJsonReq(response, *zones, zonesStr))
            {
                BMCWEB_LOG_ERROR << "Illegal Zones";
                return CreatePIDRet::fail;
            }
            if (chassis.empty() &&
                findChassis(managedObj, zonesStr[0], chassis) == nullptr)
            {
                BMCWEB_LOG_ERROR << "Failed to get chassis from config patch";
                messages::invalidObject(
                    response->res, crow::utility::urlFromPieces(
                                       "redfish", "v1", "Chassis", chassis));
                return CreatePIDRet::fail;
            }
            output.emplace_back("Zones", std::move(zonesStr));
        }

        if (inputs)
        {
            for (std::string& value : *inputs)
            {
                std::replace(value.begin(), value.end(), '_', ' ');
            }
            output.emplace_back("Inputs", *inputs);
        }

        if (outputs)
        {
            for (std::string& value : *outputs)
            {
                std::replace(value.begin(), value.end(), '_', ' ');
            }
            output.emplace_back("Outputs", *outputs);
        }

        if (setpointOffset)
        {
            // translate between redfish and dbus names
            if (*setpointOffset == "UpperThresholdNonCritical")
            {
                output.emplace_back("SetPointOffset", "WarningLow");
            }
            else if (*setpointOffset == "LowerThresholdNonCritical")
            {
                output.emplace_back("SetPointOffset", "WarningHigh");
            }
            else if (*setpointOffset == "LowerThresholdCritical")
            {
                output.emplace_back("SetPointOffset", "CriticalLow");
            }
            else if (*setpointOffset == "UpperThresholdCritical")
            {
                output.emplace_back("SetPointOffset", "CriticalHigh");
            }
            else
            {
                BMCWEB_LOG_ERROR << "Invalid setpointoffset "
                                 << *setpointOffset;
                messages::propertyValueNotInList(response->res, it.key(),
                                                 "SetPointOffset");
                return CreatePIDRet::fail;
            }
        }

        // doubles
        for (const auto& pairs : doubles)
        {
            if (!pairs.second)
            {
                continue;
            }
            BMCWEB_LOG_DEBUG << pairs.first << " = " << *pairs.second;
            output.emplace_back(pairs.first, *pairs.second);
        }
    }

    else if (type == "FanZones")
    {
        output.emplace_back("Type", "Pid.Zone");

        std::optional<nlohmann::json> chassisContainer;
        std::optional<double> failSafePercent;
        std::optional<double> minThermalOutput;
        if (!redfish::json_util::readJson(it.value(), response->res, "Chassis",
                                          chassisContainer, "FailSafePercent",
                                          failSafePercent, "MinThermalOutput",
                                          minThermalOutput))
        {
            return CreatePIDRet::fail;
        }

        if (chassisContainer)
        {

            std::string chassisId;
            if (!redfish::json_util::readJson(*chassisContainer, response->res,
                                              "@odata.id", chassisId))
            {
                return CreatePIDRet::fail;
            }

            // /redfish/v1/chassis/chassis_name/
            if (!dbus::utility::getNthStringFromPath(chassisId, 3, chassis))
            {
                BMCWEB_LOG_ERROR << "Got invalid path " << chassisId;
                messages::invalidObject(
                    response->res, crow::utility::urlFromPieces(
                                       "redfish", "v1", "Chassis", chassisId));
                return CreatePIDRet::fail;
            }
        }
        if (minThermalOutput)
        {
            output.emplace_back("MinThermalOutput", *minThermalOutput);
        }
        if (failSafePercent)
        {
            output.emplace_back("FailSafePercent", *failSafePercent);
        }
    }
    else if (type == "StepwiseControllers")
    {
        output.emplace_back("Type", "Stepwise");

        std::optional<std::vector<nlohmann::json>> zones;
        std::optional<std::vector<nlohmann::json>> steps;
        std::optional<std::vector<std::string>> inputs;
        std::optional<double> positiveHysteresis;
        std::optional<double> negativeHysteresis;
        std::optional<std::string> direction; // upper clipping curve vs lower
        if (!redfish::json_util::readJson(
                it.value(), response->res, "Zones", zones, "Steps", steps,
                "Inputs", inputs, "PositiveHysteresis", positiveHysteresis,
                "NegativeHysteresis", negativeHysteresis, "Direction",
                direction))
        {
            return CreatePIDRet::fail;
        }

        if (zones)
        {
            std::vector<std::string> zonesStrs;
            if (!getZonesFromJsonReq(response, *zones, zonesStrs))
            {
                BMCWEB_LOG_ERROR << "Illegal Zones";
                return CreatePIDRet::fail;
            }
            if (chassis.empty() &&
                findChassis(managedObj, zonesStrs[0], chassis) == nullptr)
            {
                BMCWEB_LOG_ERROR << "Failed to get chassis from config patch";
                messages::invalidObject(
                    response->res, crow::utility::urlFromPieces(
                                       "redfish", "v1", "Chassis", chassis));
                return CreatePIDRet::fail;
            }
            output.emplace_back("Zones", std::move(zonesStrs));
        }
        if (steps)
        {
            std::vector<double> readings;
            std::vector<double> outputs;
            for (auto& step : *steps)
            {
                double target = 0.0;
                double out = 0.0;

                if (!redfish::json_util::readJson(step, response->res, "Target",
                                                  target, "Output", out))
                {
                    return CreatePIDRet::fail;
                }
                readings.emplace_back(target);
                outputs.emplace_back(out);
            }
            output.emplace_back("Reading", std::move(readings));
            output.emplace_back("Output", std::move(outputs));
        }
        if (inputs)
        {
            for (std::string& value : *inputs)
            {

                std::replace(value.begin(), value.end(), '_', ' ');
            }
            output.emplace_back("Inputs", std::move(*inputs));
        }
        if (negativeHysteresis)
        {
            output.emplace_back("NegativeHysteresis", *negativeHysteresis);
        }
        if (positiveHysteresis)
        {
            output.emplace_back("PositiveHysteresis", *positiveHysteresis);
        }
        if (direction)
        {
            constexpr const std::array<const char*, 2> allowedDirections = {
                "Ceiling", "Floor"};
            if (std::find(allowedDirections.begin(), allowedDirections.end(),
                          *direction) == allowedDirections.end())
            {
                messages::propertyValueTypeError(response->res, "Direction",
                                                 *direction);
                return CreatePIDRet::fail;
            }
            output.emplace_back("Class", *direction);
        }
    }
    else
    {
        BMCWEB_LOG_ERROR << "Illegal Type " << type;
        messages::propertyUnknown(response->res, type);
        return CreatePIDRet::fail;
    }
    return CreatePIDRet::patch;
}
struct GetPIDValues : std::enable_shared_from_this<GetPIDValues>
{
    struct CompletionValues
    {
        std::vector<std::string> supportedProfiles;
        std::string currentProfile;
        dbus::utility::MapperGetSubTreeResponse subtree;
    };

    explicit GetPIDValues(
        const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn) :
        asyncResp(asyncRespIn)

    {}

    void run()
    {
        std::shared_ptr<GetPIDValues> self = shared_from_this();

        // get all configurations
        constexpr std::array<std::string_view, 4> interfaces = {
            pidConfigurationIface, pidZoneConfigurationIface,
            objectManagerIface, stepwiseConfigurationIface};
        managedStore::ManagedObjectStoreContext requestContext(asyncResp);
        managedStore::GetManagedObjectStore()->getSubTree(
            "/", 0, interfaces, requestContext,
            [self](
                const boost::system::error_code& ec,
                const dbus::utility::MapperGetSubTreeResponse& subtreeLocal) {
            if (ec)
            {
                BMCWEB_LOG_ERROR << "GetPIDValues: " << ec;
                messages::internalError(self->asyncResp->res);
                return;
            }
            self->complete.subtree = subtreeLocal;
        });

        // at the same time get the selected profile
        constexpr std::array<std::string_view, 1> thermalModeIfaces = {
            thermalModeIface};
        managedStore::GetManagedObjectStore()->getSubTree(
            "/", 0, thermalModeIfaces, requestContext,
            [self](
                const boost::system::error_code& ec,
                const dbus::utility::MapperGetSubTreeResponse& subtreeLocal) {
            if (ec)
            {
                BMCWEB_LOG_ERROR << "GetPIDValues: " << ec;
                messages::internalError(self->asyncResp->res);
                return;
            }
            if (subtreeLocal.empty())
            {
                // This is not to be considered an error
                BMCWEB_LOG_WARNING << "GetPIDValues: Empty subtree";
                return;
            }
            if (subtreeLocal[0].second.size() != 1)
            {
                // invalid mapper response, should never happen
                BMCWEB_LOG_ERROR << "GetPIDValues: Mapper Error";
                messages::internalError(self->asyncResp->res);
                return;
            }

            const std::string& path = subtreeLocal[0].first;
            const std::string& owner = subtreeLocal[0].second[0].first;

            managedStore::ManagedObjectStoreContext context(self->asyncResp);
            managedStore::GetManagedObjectStore()->getAllProperties(
                owner, path, thermalModeIface, context,
                [path, owner,
                 self](const boost::system::error_code& ec2,
                       const dbus::utility::DBusPropertiesMap& resp) {
                if (ec2)
                {
                    BMCWEB_LOG_ERROR
                        << "GetPIDValues: Can't get thermalModeIface " << path << ": " << ec2;
                    messages::internalError(self->asyncResp->res);
                    return;
                }

                const std::string* current = nullptr;
                const std::vector<std::string>* supported = nullptr;

                const bool success = sdbusplus::unpackPropertiesNoThrow(
                    dbus_utils::UnpackErrorPrinter(), resp, "Current", current,
                    "Supported", supported);

                if (!success)
                {
                    BMCWEB_LOG_ERROR << "GetPIDValues: Error unpacking";
                    messages::internalError(self->asyncResp->res);
                    return;
                }

                if (current == nullptr || supported == nullptr)
                {
                    BMCWEB_LOG_ERROR
                        << "GetPIDValues: thermal mode iface invalid " << path;
                    messages::internalError(self->asyncResp->res);
                    return;
                }
                self->complete.currentProfile = *current;
                self->complete.supportedProfiles = *supported;
            });
        });
    }

    static void
        processingComplete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                           const CompletionValues& completion)
    {
        if (asyncResp->res.result() != boost::beast::http::status::ok)
        {
            return;
        }
        // create map of <connection, path to objMgr>>
        boost::container::flat_map<
            std::string, std::string, std::less<>,
            std::vector<std::pair<std::string, std::string>>>
            objectMgrPaths;
        boost::container::flat_set<std::string, std::less<>,
                                   std::vector<std::string>>
            calledConnections;
        for (const auto& pathGroup : completion.subtree)
        {
            for (const auto& connectionGroup : pathGroup.second)
            {
                auto findConnection =
                    calledConnections.find(connectionGroup.first);
                if (findConnection != calledConnections.end())
                {
                    break;
                }
                for (const std::string& interface : connectionGroup.second)
                {
                    if (interface == objectManagerIface)
                    {
                        objectMgrPaths[connectionGroup.first] = pathGroup.first;
                    }
                    // this list is alphabetical, so we
                    // should have found the objMgr by now
                    if (interface == pidConfigurationIface ||
                        interface == pidZoneConfigurationIface ||
                        interface == stepwiseConfigurationIface)
                    {
                        auto findObjMgr =
                            objectMgrPaths.find(connectionGroup.first);
                        if (findObjMgr == objectMgrPaths.end())
                        {
                            BMCWEB_LOG_DEBUG << connectionGroup.first
                                             << "Has no Object Manager";
                            continue;
                        }

                        calledConnections.insert(connectionGroup.first);

                        asyncPopulatePid(findObjMgr->first, findObjMgr->second,
                                         completion.currentProfile,
                                         completion.supportedProfiles,
                                         asyncResp);
                        break;
                    }
                }
            }
        }
    }

    ~GetPIDValues()
    {
        boost::asio::post(managedStore::GetManagedObjectStore()->GetIoContext(),
                          std::bind_front(&processingComplete, asyncResp,
                                          std::move(complete)));
    }

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

    std::shared_ptr<bmcweb::AsyncResp> asyncResp;
    CompletionValues complete;
};

struct SetPIDValues : std::enable_shared_from_this<SetPIDValues>
{
    SetPIDValues(const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn,
                 nlohmann::json& data) :
        asyncResp(asyncRespIn)
    {
        std::optional<nlohmann::json> pidControllers;
        std::optional<nlohmann::json> fanControllers;
        std::optional<nlohmann::json> fanZones;
        std::optional<nlohmann::json> stepwiseControllers;

        if (!redfish::json_util::readJson(
                data, asyncResp->res, "PidControllers", pidControllers,
                "FanControllers", fanControllers, "FanZones", fanZones,
                "StepwiseControllers", stepwiseControllers, "Profile", profile))
        {
            return;
        }
        configuration.emplace_back("PidControllers", std::move(pidControllers));
        configuration.emplace_back("FanControllers", std::move(fanControllers));
        configuration.emplace_back("FanZones", std::move(fanZones));
        configuration.emplace_back("StepwiseControllers",
                                   std::move(stepwiseControllers));
    }

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

    void run()
    {
        if (asyncResp->res.result() != boost::beast::http::status::ok)
        {
            return;
        }

        std::shared_ptr<SetPIDValues> self = shared_from_this();

        // todo(james): might make sense to do a mapper call here if this
        // interface gets more traction
        managedStore::ManagedObjectStoreContext context(asyncResp);
        managedStore::GetManagedObjectStore()->getManagedObjectsWithContext(
            "xyz.openbmc_project.EntityManager",
            {"/xyz/openbmc_project/inventory"}, context,
            [self](const boost::system::error_code& ec,
                   const dbus::utility::ManagedObjectType& mObj) {
            if (ec)
            {
                BMCWEB_LOG_ERROR << "Error communicating to Entity Manager";
                messages::internalError(self->asyncResp->res);
                return;
            }
            const std::array<const char*, 3> configurations = {
                pidConfigurationIface, pidZoneConfigurationIface,
                stepwiseConfigurationIface};

            for (const auto& [path, object] : mObj)
            {
                for (const auto& [interface, _] : object)
                {
                    if (std::find(configurations.begin(), configurations.end(),
                                  interface) != configurations.end())
                    {
                        self->objectCount++;
                        break;
                    }
                }
            }
            self->managedObj = mObj;
            });

        // at the same time get the profile information
        constexpr std::array<std::string_view, 1> thermalModeIfaces = {
            thermalModeIface};
        managedStore::GetManagedObjectStore()->getSubTree(
            "/", 0, thermalModeIfaces, context,
            [self,
             context](const boost::system::error_code& ec,
                      const dbus::utility::MapperGetSubTreeResponse& subtree) {
            if (ec)
            {
                BMCWEB_LOG_ERROR << "SetPIDValues: " << ec;
                messages::internalError(self->asyncResp->res);
                return;
            }
            if (subtree.empty())
            {
                // This is not to be considered an error
                BMCWEB_LOG_WARNING << "SetPIDValues: Empty subtree";
                return;
            }
            if (subtree[0].second.empty())
            {
                // invalid mapper response, should never happen
                BMCWEB_LOG_ERROR << "SetPIDValues: Mapper Error";
                messages::internalError(self->asyncResp->res);
                return;
            }

            const std::string& path = subtree[0].first;
            const std::string& owner = subtree[0].second[0].first;
            managedStore::GetManagedObjectStore()->getAllProperties(
                owner, path, thermalModeIface, context,
                [self, path, owner](const boost::system::error_code& ec2,
                                    const dbus::utility::DBusPropertiesMap& r) {
                if (ec2)
                {
                    BMCWEB_LOG_ERROR
                        << "SetPIDValues: Can't get thermalModeIface " << path;
                    messages::internalError(self->asyncResp->res);
                    return;
                }
                const std::string* current = nullptr;
                const std::vector<std::string>* supported = nullptr;

                const bool success = sdbusplus::unpackPropertiesNoThrow(
                    dbus_utils::UnpackErrorPrinter(), r, "Current", current,
                    "Supported", supported);

                if (!success)
                {
                    messages::internalError(self->asyncResp->res);
                    return;
                }

                if (current == nullptr || supported == nullptr)
                {
                    BMCWEB_LOG_ERROR
                        << "SetPIDValues: thermal mode iface invalid " << path;
                    messages::internalError(self->asyncResp->res);
                    return;
                }
                self->currentProfile = *current;
                self->supportedProfiles = *supported;
                self->profileConnection = owner;
                self->profilePath = path;
                });
            });
    }
    void pidSetDone()
    {
        if (asyncResp->res.result() != boost::beast::http::status::ok)
        {
            return;
        }
        std::shared_ptr<bmcweb::AsyncResp> response = asyncResp;
        if (profile)
        {
            if (std::find(supportedProfiles.begin(), supportedProfiles.end(),
                          *profile) == supportedProfiles.end())
            {
                messages::actionParameterUnknown(response->res, "Profile",
                                                 *profile);
                return;
            }
            currentProfile = *profile;
            managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
                response->strand_,
                [response](const boost::system::error_code& ec) {
                if (ec)
                {
                    BMCWEB_LOG_ERROR << "Error patching profile" << ec;
                    messages::internalError(response->res);
                }
                },
                profileConnection, profilePath,
                "org.freedesktop.DBus.Properties", "Set", thermalModeIface,
                "Current", dbus::utility::DbusVariantType(*profile));
        }

        for (auto& containerPair : configuration)
        {
            auto& container = containerPair.second;
            if (!container)
            {
                continue;
            }
            BMCWEB_LOG_DEBUG << *container;

            const std::string& type = containerPair.first;

            for (nlohmann::json::iterator it = container->begin();
                 it != container->end(); ++it)
            {
                const auto& name = it.key();
                BMCWEB_LOG_DEBUG << "looking for " << name;

                auto pathItr =
                    std::find_if(managedObj.begin(), managedObj.end(),
                                 [&name](const auto& obj) {
                    return boost::algorithm::ends_with(obj.first.str,
                                                       "/" + name);
                    });
                dbus::utility::DBusPropertiesMap output;

                output.reserve(16); // The pid interface length

                // determines if we're patching entity-manager or
                // creating a new object
                bool createNewObject = (pathItr == managedObj.end());
                BMCWEB_LOG_DEBUG << "Found = " << !createNewObject;

                std::string iface;
                if (!createNewObject)
                {
                    bool findInterface = false;
                    for (const auto& interface : pathItr->second)
                    {
                        if (interface.first == pidConfigurationIface)
                        {
                            if (type == "PidControllers" ||
                                type == "FanControllers")
                            {
                                iface = pidConfigurationIface;
                                findInterface = true;
                                break;
                            }
                        }
                        else if (interface.first == pidZoneConfigurationIface)
                        {
                            if (type == "FanZones")
                            {
                                iface = pidConfigurationIface;
                                findInterface = true;
                                break;
                            }
                        }
                        else if (interface.first == stepwiseConfigurationIface)
                        {
                            if (type == "StepwiseControllers")
                            {
                                iface = stepwiseConfigurationIface;
                                findInterface = true;
                                break;
                            }
                        }
                    }

                    // create new object if interface not found
                    if (!findInterface)
                    {
                        createNewObject = true;
                    }
                }

                if (createNewObject && it.value() == nullptr)
                {
                    // can't delete a non-existent object
                    messages::propertyValueNotInList(response->res,
                                                     it.value().dump(), name);
                    continue;
                }

                std::string path;
                if (pathItr != managedObj.end())
                {
                    path = pathItr->first.str;
                }

                BMCWEB_LOG_DEBUG << "Create new = " << createNewObject << "\n";

                // arbitrary limit to avoid attacks
                constexpr const size_t controllerLimit = 500;
                if (createNewObject && objectCount >= controllerLimit)
                {
                    messages::resourceExhaustion(response->res, type);
                    continue;
                }
                std::string escaped = name;
                std::replace(escaped.begin(), escaped.end(), '_', ' ');
                output.emplace_back("Name", escaped);

                std::string chassis;
                CreatePIDRet ret = createPidInterface(
                    response, type, it, path, managedObj, createNewObject,
                    output, chassis, currentProfile);
                if (ret == CreatePIDRet::fail)
                {
                    return;
                }
                if (ret == CreatePIDRet::del)
                {
                    continue;
                }

                if (!createNewObject)
                {
                    for (const auto& property : output)
                    {
                        managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
                            response->strand_,
                            [response,
                             propertyName{std::string(property.first)}](
                                const boost::system::error_code& ec) {
                            if (ec)
                            {
                                BMCWEB_LOG_ERROR << "Error patching "
                                                 << propertyName << ": " << ec;
                                messages::internalError(response->res);
                                return;
                            }
                            messages::success(response->res);
                            },
                            "xyz.openbmc_project.EntityManager", path,
                            "org.freedesktop.DBus.Properties", "Set", iface,
                            property.first, dbus::utility::DbusVariantType{property.second});
                    }
                }
                else
                {
                    if (chassis.empty())
                    {
                        BMCWEB_LOG_ERROR << "Failed to get chassis from config";
                        messages::internalError(response->res);
                        return;
                    }

                    bool foundChassis = false;
                    for (const auto& obj : managedObj)
                    {
                        if (boost::algorithm::ends_with(obj.first.str, chassis))
                        {
                            chassis = obj.first.str;
                            foundChassis = true;
                            break;
                        }
                    }
                    if (!foundChassis)
                    {
                        BMCWEB_LOG_ERROR << "Failed to find chassis on dbus";
                        messages::resourceMissingAtURI(
                            response->res,
                            crow::utility::urlFromPieces("redfish", "v1",
                                                         "Chassis", chassis));
                        return;
                    }

                    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
                        response->strand_,
                        [response](const boost::system::error_code& ec) {
                        if (ec)
                        {
                            BMCWEB_LOG_ERROR << "Error Adding Pid Object "
                                             << ec;
                            messages::internalError(response->res);
                            return;
                        }
                        messages::success(response->res);
                        },
                        "xyz.openbmc_project.EntityManager", chassis,
                        "xyz.openbmc_project.AddObject", "AddObject", output);
                }
            }
        }
    }

    ~SetPIDValues()
    {
        try
        {
            pidSetDone();
        }
        catch (...)
        {
            BMCWEB_LOG_CRITICAL << "pidSetDone threw exception";
        }
    }

    std::shared_ptr<bmcweb::AsyncResp> asyncResp;
    std::vector<std::pair<std::string, std::optional<nlohmann::json>>>
        configuration;
    std::optional<std::string> profile;
    dbus::utility::ManagedObjectType managedObj;
    std::vector<std::string> supportedProfiles;
    std::string currentProfile;
    std::string profileConnection;
    std::string profilePath;
    size_t objectCount = 0;
};

// avoid name collision systems.hpp
inline void
    managerGetLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
{
    BMCWEB_LOG_DEBUG << "Getting Manager Last Reset Time";

    managedStore::ManagedObjectStoreContext requestContext(aResp);
    dbus_utils::getProperty<uint64_t>(
        "xyz.openbmc_project.State.BMC", "/xyz/openbmc_project/state/bmc0",
        "xyz.openbmc_project.State.BMC", "LastRebootTime", requestContext,
        [aResp](const boost::system::error_code& ec,
                const uint64_t lastResetTime) {
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
            return;
        }

        // LastRebootTime is epoch time, in milliseconds
        // https://github.com/openbmc/phosphor-dbus-interfaces/blob/7f9a128eb9296e926422ddc312c148b625890bb6/xyz/openbmc_project/State/BMC.interface.yaml#L19
        uint64_t lastResetTimeStamp = lastResetTime / 1000;

        // Convert to ISO 8601 standard
        aResp->res.jsonValue["LastResetTime"] =
            redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
        });
}

/**
 * @brief Set the running firmware image
 *
 * @param[i,o] aResp - Async response object
 * @param[i] runningFirmwareTarget - Image to make the running image
 *
 * @return void
 */
inline void
    setActiveFirmwareImage(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                           const std::string& runningFirmwareTarget)
{
    // Get the Id from /redfish/v1/UpdateService/FirmwareInventory/<Id>
    std::string::size_type idPos = runningFirmwareTarget.rfind('/');
    if (idPos == std::string::npos)
    {
        messages::propertyValueNotInList(aResp->res, runningFirmwareTarget,
                                         "@odata.id");
        BMCWEB_LOG_DEBUG << "Can't parse firmware ID!";
        return;
    }
    idPos++;
    if (idPos >= runningFirmwareTarget.size())
    {
        messages::propertyValueNotInList(aResp->res, runningFirmwareTarget,
                                         "@odata.id");
        BMCWEB_LOG_DEBUG << "Invalid firmware ID.";
        return;
    }
    std::string firmwareId = runningFirmwareTarget.substr(idPos);

    managedStore::ManagedObjectStoreContext context(aResp);
    // Make sure the image is valid before setting priority
    managedStore::GetManagedObjectStore()->getManagedObjectsWithContext(
        "xyz.openbmc_project.Software.BMC.Updater",
        {"/xyz/openbmc_project/software"}, context,
        [aResp, firmwareId, runningFirmwareTarget](
            const boost::system::error_code& ec,
            const dbus::utility::ManagedObjectType& subtree) {
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "D-Bus response error getting objects.";
            messages::internalError(aResp->res);
            return;
        }

        if (subtree.empty())
        {
            BMCWEB_LOG_DEBUG << "Can't find image!";
            messages::internalError(aResp->res);
            return;
        }

        bool foundImage = false;
        for (const auto& object : subtree)
        {
            const std::string& path =
                static_cast<const std::string&>(object.first);
            std::size_t idPos2 = path.rfind('/');

            if (idPos2 == std::string::npos)
            {
                continue;
            }

            idPos2++;
            if (idPos2 >= path.size())
            {
                continue;
            }

            if (path.substr(idPos2) == firmwareId)
            {
                foundImage = true;
                break;
            }
        }

        if (!foundImage)
        {
            messages::propertyValueNotInList(aResp->res, runningFirmwareTarget,
                                             "@odata.id");
            BMCWEB_LOG_DEBUG << "Invalid firmware ID.";
            return;
        }

        BMCWEB_LOG_DEBUG << "Setting firmware version " << firmwareId
                         << " to priority 0.";

        // Only support Immediate
        // An addition could be a Redfish Setting like
        // ActiveSoftwareImageApplyTime and support OnReset
        managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
            aResp->strand_,
            [aResp](const boost::system::error_code& ec2) {
            if (ec2)
            {
                BMCWEB_LOG_DEBUG << "D-Bus response error setting.";
                messages::internalError(aResp->res);
                return;
            }
            doBMCGracefulRestart(aResp);
            },

            "xyz.openbmc_project.Software.BMC.Updater",
            "/xyz/openbmc_project/software/" + firmwareId,
            "org.freedesktop.DBus.Properties", "Set",
            "xyz.openbmc_project.Software.RedundancyPriority", "Priority",
            dbus::utility::DbusVariantType(static_cast<uint8_t>(0)));
        });
}

inline void setDateTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                        std::string datetime)
{
    BMCWEB_LOG_DEBUG << "Set date time: " << datetime;

    std::optional<redfish::time_utils::usSinceEpoch> us =
        redfish::time_utils::dateStringToEpoch(datetime);
    if (!us)
    {
        messages::propertyValueFormatError(aResp->res, datetime, "DateTime");
        return;
    }
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        aResp->strand_,
        [aResp,
         datetime{std::move(datetime)}](const boost::system::error_code& ec) {
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "Failed to set elapsed time. "
                                "DBUS response error "
                             << ec;
            messages::internalError(aResp->res);
            return;
        }
        aResp->res.jsonValue["DateTime"] = datetime;
        },
        "xyz.openbmc_project.Time.Manager", "/xyz/openbmc_project/time/bmc",
        "org.freedesktop.DBus.Properties", "Set",
        "xyz.openbmc_project.Time.EpochTime", "Elapsed",
        dbus::utility::DbusVariantType(us->count()));
}

inline void
    handleManagerGet(App& app,
                     const crow::Request& req,
                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Managers/bmc";
    asyncResp->res.jsonValue["@odata.type"] = "#Manager.v1_16_0.Manager";
    asyncResp->res.jsonValue["Id"] = "bmc";
    asyncResp->res.jsonValue["Name"] = "OpenBmc Manager";
    asyncResp->res.jsonValue["Description"] = "Baseboard Management Controller";
    asyncResp->res.jsonValue["PowerState"] = "On";
    asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
    asyncResp->res.jsonValue["Status"]["Health"] = "OK";

    asyncResp->res.jsonValue["ManagerType"] = "BMC";
    asyncResp->res.jsonValue["UUID"] = systemd_utils::getUuid();
    asyncResp->res.jsonValue["ServiceEntryPointUUID"] = persistent_data::getConfig().systemUuid;
    asyncResp->res.jsonValue["Model"] = "OpenBmc"; // TODO(ed), get model

    asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
        "/redfish/v1/Managers/bmc/LogServices";
    asyncResp->res.jsonValue["NetworkProtocol"]["@odata.id"] =
        "/redfish/v1/Managers/bmc/NetworkProtocol";
    asyncResp->res.jsonValue["EthernetInterfaces"]["@odata.id"] =
        "/redfish/v1/Managers/bmc/EthernetInterfaces";
    asyncResp->res.jsonValue["DedicatedNetworkPorts"]["@odata.id"] =
        "/redfish/v1/Managers/bmc/DedicatedNetworkPorts";

#ifdef BMCWEB_ENABLE_VM_NBDPROXY
    asyncResp->res.jsonValue["VirtualMedia"]["@odata.id"] =
        "/redfish/v1/Managers/bmc/VirtualMedia";
#endif // BMCWEB_ENABLE_VM_NBDPROXY

    // default oem data
    nlohmann::json& oem = asyncResp->res.jsonValue["Oem"];
    nlohmann::json& oemOpenbmc = oem["OpenBmc"];
    oem["@odata.type"] = "#OemManager.Oem";
    oem["@odata.id"] = "/redfish/v1/Managers/bmc#/Oem";
    oemOpenbmc["@odata.type"] = "#OemManager.OpenBmc";
    oemOpenbmc["@odata.id"] = "/redfish/v1/Managers/bmc#/Oem/OpenBmc";

    nlohmann::json::object_t certificates;
    certificates["@odata.id"] =
        "/redfish/v1/Managers/bmc/Truststore/Certificates";
    oemOpenbmc["Certificates"] = std::move(certificates);

    // Manager.Reset (an action) can be many values, OpenBMC only
    // supports BMC reboot.
    nlohmann::json& managerReset =
        asyncResp->res.jsonValue["Actions"]["#Manager.Reset"];
    managerReset["target"] = "/redfish/v1/Managers/bmc/Actions/Manager.Reset";
    managerReset["@Redfish.ActionInfo"] =
        "/redfish/v1/Managers/bmc/ResetActionInfo";

    // ResetToDefaults (Factory Reset) has values like
    // PreserveNetworkAndUsers and PreserveNetwork that aren't supported
    // on OpenBMC
    nlohmann::json& resetToDefaults =
        asyncResp->res.jsonValue["Actions"]["#Manager.ResetToDefaults"];
    resetToDefaults["target"] =
        "/redfish/v1/Managers/bmc/Actions/Manager.ResetToDefaults";
    resetToDefaults["ResetType@Redfish.AllowableValues"] =
        nlohmann::json::array_t({"ResetAll"});

    nlohmann::json& fanModeChange =
        asyncResp->res.jsonValue["Actions"]["#Manager.FanMode.Change"];
    fanModeChange["target"] =
        "/redfish/v1/Managers/bmc/Actions/Manager.FanMode.Change";
    fanModeChange["@Redfish.ActionInfo"] =
        "/redfish/v1/Managers/bmc/FanMode.Change.ActionInfo";

    std::pair<std::string, std::string> redfishDateTimeOffset =
        redfish::time_utils::getDateTimeOffsetNow();

    asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
    asyncResp->res.jsonValue["DateTimeLocalOffset"] =
        redfishDateTimeOffset.second;

    // TODO (Gunnar): Remove these one day since moved to ComputerSystem
    // Still used by OCP profiles
    // https://github.com/opencomputeproject/OCP-Profiles/issues/23
    // Fill in SerialConsole info
    asyncResp->res.jsonValue["SerialConsole"]["ServiceEnabled"] = true;
    asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
    asyncResp->res.jsonValue["SerialConsole"]["ConnectTypesSupported"] =
        nlohmann::json::array_t({"IPMI", "SSH"});
#ifdef BMCWEB_ENABLE_KVM
    // Fill in GraphicalConsole info
    asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
    asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
    asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
        nlohmann::json::array_t({"KVMIP"});
#endif // BMCWEB_ENABLE_KVM

    asyncResp->res.jsonValue["Links"]["ManagerForServers@odata.count"] = 1;

    nlohmann::json::array_t managerForServers;
    nlohmann::json::object_t manager;
    manager["@odata.id"] = "/redfish/v1/Systems/system";
    managerForServers.emplace_back(std::move(manager));

    asyncResp->res.jsonValue["Links"]["ManagerForServers"] =
        std::move(managerForServers);

#ifdef HEALTH_POPULATE
    auto health = std::make_shared<HealthPopulate>(asyncResp);
    health->isManagersHealth = true;
    health->populate();
#endif

    sw_util::populateSoftwareInformation(asyncResp, sw_util::bmcPurpose,
                                         "FirmwareVersion", true);

    managerGetLastResetTime(asyncResp);

    // ManagerDiagnosticData is added for all BMCs.
    nlohmann::json& managerDiagnosticData =
        asyncResp->res.jsonValue["ManagerDiagnosticData"];
    managerDiagnosticData["@odata.id"] =
        "/redfish/v1/Managers/bmc/ManagerDiagnosticData";

#ifdef BMCWEB_ENABLE_REDFISH_BOOT_TIME
    asyncResp->res.jsonValue["Oem"]["Google"]["BootTime"]["@odata.id"] =
        "/redfish/v1/Managers/bmc/Oem/Google/BootTime";
#endif

#ifdef BMCWEB_ENABLE_REDFISH_OEM_MANAGER_FAN_DATA
    auto pids = std::make_shared<GetPIDValues>(asyncResp);
    pids->run();
#endif

    getMainChassisId(asyncResp,
                     [](const std::string& chassisId,
                        const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
        aRsp->res.jsonValue["Links"]["ManagerForChassis@odata.count"] = 1;
        nlohmann::json::array_t managerForChassis;
        nlohmann::json::object_t managerObj;
        boost::urls::url chassiUrl =
            crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId);
        managerObj["@odata.id"] = chassiUrl;
        managerForChassis.emplace_back(std::move(managerObj));
        aRsp->res.jsonValue["Links"]["ManagerForChassis"] =
            std::move(managerForChassis);
    });

    getBmcChassisId(asyncResp,
                    [](const std::string& chassisId,
                       const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
        boost::urls::url chassiUrl =
            crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId);
        aRsp->res.jsonValue["Links"]["ManagerInChassis"]["@odata.id"] =
            chassiUrl;
    });

    static bool started = false;
    asyncResp->res.jsonValue["Location"]["PartLocation"]["LocationType"] =
        "Embedded";
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);

    if (!started)
    {
        dbus_utils::getProperty<double>(
            "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
            "org.freedesktop.systemd1.Manager", "Progress", requestContext,
            [asyncResp](const boost::system::error_code& ec,
                        const double& val) {
            if (ec)
            {
                BMCWEB_LOG_ERROR << "Error while getting progress";
                messages::internalError(asyncResp->res);
                return;
            }
            if (val < 1.0)
            {
                asyncResp->res.jsonValue["Status"]["State"] = "Starting";
                started = true;
            }
        });
    }

    constexpr std::array<std::string_view, 1> interfaces = {
        "xyz.openbmc_project.Inventory.Item.Bmc"};
    managedStore::GetManagedObjectStore()->getSubTree(
        "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
        [asyncResp, requestContext](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
            return;
        }
        if (subtree.empty())
        {
            BMCWEB_LOG_DEBUG << "Can't find bmc D-Bus object!";
            return;
        }
        // Assume only 1 bmc D-Bus object
        // Throw an error if there is more than 1
        if (subtree.size() > 1)
        {
            BMCWEB_LOG_DEBUG << "Found more than 1 bmc D-Bus object!";
            messages::internalError(asyncResp->res);
            return;
        }

        if (subtree[0].first.empty() || subtree[0].second.size() != 1)
        {
            BMCWEB_LOG_DEBUG << "Error getting bmc D-Bus object!";
            messages::internalError(asyncResp->res);
            return;
        }

        const std::string& path = subtree[0].first;
        const std::string& connectionName = subtree[0].second[0].first;

        for (const auto& interfaceName : subtree[0].second[0].second)
        {
            if (interfaceName ==
                "xyz.openbmc_project.Inventory.Decorator.Asset")
            {

                managedStore::GetManagedObjectStore()->getAllProperties(
                    connectionName, path,
                    "xyz.openbmc_project.Inventory.Decorator.Asset",
                    requestContext,
                    [asyncResp](const boost::system::error_code& ec2,
                                const dbus::utility::DBusPropertiesMap&
                                    propertiesList) {
                    if (ec2)
                    {
                        BMCWEB_LOG_DEBUG << "Can't get bmc asset!";
                        return;
                    }

                    const std::string* partNumber = nullptr;
                    const std::string* serialNumber = nullptr;
                    const std::string* manufacturer = nullptr;
                    const std::string* model = nullptr;
                    const std::string* sparePartNumber = nullptr;

                    const bool success = sdbusplus::unpackPropertiesNoThrow(
                        dbus_utils::UnpackErrorPrinter(), propertiesList,
                        "PartNumber", partNumber, "SerialNumber", serialNumber,
                        "Manufacturer", manufacturer, "Model", model,
                        "SparePartNumber", sparePartNumber);

                    if (!success)
                    {
                        messages::internalError(asyncResp->res);
                        return;
                    }

                    if (partNumber != nullptr)
                    {
                        asyncResp->res.jsonValue["PartNumber"] = *partNumber;
                    }

                    if (serialNumber != nullptr)
                    {
                        asyncResp->res.jsonValue["SerialNumber"] =
                            *serialNumber;
                    }

                    if (manufacturer != nullptr)
                    {
                        asyncResp->res.jsonValue["Manufacturer"] =
                            *manufacturer;
                    }

                    if (model != nullptr)
                    {
                        asyncResp->res.jsonValue["Model"] = *model;
                    }

                    if (sparePartNumber != nullptr)
                    {
                        asyncResp->res.jsonValue["SparePartNumber"] =
                            *sparePartNumber;
                    }
                });
            }
            else if (interfaceName ==
                     "xyz.openbmc_project.Inventory.Decorator.LocationCode")
            {
                location_util::getLocationCode(asyncResp, connectionName, path,
                                               "/Location"_json_pointer);
                location_util::getPartLocationContext(asyncResp,
                                                      "/Location"_json_pointer,
                                                      path + "/contained_by");
                asyncResp->res.jsonValue["Location"]["Oem"]["Google"]
                                        ["EmbeddedLocationContext"] =
                    "openbmc_manager";
            }
        }
    });
}

inline void
    handleManagerPatch(App& app, const crow::Request& req,
                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    std::optional<nlohmann::json> oem;
    std::optional<nlohmann::json> links;
    std::optional<std::string> datetime;

    if (!json_util::readJsonPatch(req, asyncResp->res, "Oem", oem, "DateTime",
                                  datetime, "Links", links))
    {
        return;
    }

    if (oem)
    {
#ifdef BMCWEB_ENABLE_REDFISH_OEM_MANAGER_FAN_DATA
        std::optional<nlohmann::json> openbmc;
        if (!redfish::json_util::readJson(*oem, asyncResp->res, "OpenBmc",
                                          openbmc))
        {
            return;
        }
        if (openbmc)
        {
            std::optional<nlohmann::json> fan;
            if (!redfish::json_util::readJson(*openbmc, asyncResp->res, "Fan",
                                              fan))
            {
                return;
            }
            if (fan)
            {
                auto pid = std::make_shared<SetPIDValues>(asyncResp, *fan);
                pid->run();
            }
        }
#else
        messages::propertyUnknown(asyncResp->res, "Oem");
        return;
#endif
    }
    if (links)
    {
        std::optional<nlohmann::json> activeSoftwareImage;
        if (!redfish::json_util::readJson(*links, asyncResp->res,
                                          "ActiveSoftwareImage",
                                          activeSoftwareImage))
        {
            return;
        }
        if (activeSoftwareImage)
        {
            std::optional<std::string> odataId;
            if (!json_util::readJson(*activeSoftwareImage, asyncResp->res,
                                     "@odata.id", odataId))
            {
                return;
            }

            if (odataId)
            {
                setActiveFirmwareImage(asyncResp, *odataId);
            }
        }
    }
    if (datetime)
    {
        setDateTime(asyncResp, std::move(*datetime));
    }
}

inline void requestRoutesManager(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/")
        .privileges(redfish::privileges::getManager)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleManagerGet, std::ref(app)));

    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/")
        .privileges(redfish::privileges::patchManager)
        .methods(boost::beast::http::verb::patch)(
            std::bind_front(handleManagerPatch, std::ref(app)));
}

inline void handleGetManagerCollection(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    // Collections don't include the static data added by SubRoute
    // because it has a duplicate entry for members
    asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Managers";
    asyncResp->res.jsonValue["@odata.type"] =
        "#ManagerCollection.ManagerCollection";
    asyncResp->res.jsonValue["Name"] = "Manager Collection";
    nlohmann::json& members = asyncResp->res.jsonValue["Members"];
    if (!members.is_array())
    {
        // With Redfish aggregation, top level collections can have their
        // Members array already created if a satellite response has been
        // processed first.  In that case we don't want to clobber the
        // aggregated data
        members = nlohmann::json::array();
    }
    nlohmann::json::object_t bmc;
    bmc["@odata.id"] = "/redfish/v1/Managers/bmc";
    members.emplace_back(std::move(bmc));
    asyncResp->res.jsonValue["Members@odata.count"] = members.size();
}

inline void requestRoutesManagerCollection(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Managers/")
        .privileges(redfish::privileges::getManagerCollection)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleGetManagerCollection, std::ref(app)));
}

inline void handleBmcBootTimeDataGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    boot_time_utils::PopulateDefaultBootTimeProperties(asyncResp);
    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/Managers/bmc/Oem/Google/BootTime";

    std::shared_ptr<std::vector<boot_time_utils::Checkpoint>> bmcCheckpoints =
        std::make_shared<std::vector<boot_time_utils::Checkpoint>>();
    std::shared_ptr<std::vector<boot_time_utils::Duration>> bmcDurations =
        std::make_shared<std::vector<boot_time_utils::Duration>>();
    std::shared_ptr<bool> bmcIsRebooting = std::make_shared<bool>(false);
    std::shared_ptr<int> waitingForLoadingData = std::make_shared<int>(3);
    std::shared_ptr<bool> errorOccurred = std::make_shared<bool>(false);

    std::function<void()> dbusSuccessCallback =
        [asyncResp, bmcCheckpoints, bmcDurations, bmcIsRebooting,
         waitingForLoadingData, errorOccurred]() {
        --(*waitingForLoadingData);
        if (*waitingForLoadingData == 0 && !*errorOccurred)
        {
            boot_time_utils::GetBmcBreakdownStages(asyncResp, bmcCheckpoints);
            boot_time_utils::PopulateDurationInResponse(asyncResp,
                                                        bmcDurations);
            boot_time_utils::GetBmcRebootFlow(asyncResp, bmcCheckpoints);
            boot_time_utils::PopulateTotalTimeInResponse(
                asyncResp, bmcCheckpoints, bmcDurations);
            boot_time_utils::PopulateStatPowerSourceInResponse(asyncResp,
                                                               bmcCheckpoints);
            boot_time_utils::PopulateStatIsRebootingInResponse(asyncResp,
                                                               bmcIsRebooting);
        }
    };
    std::function<void()> dbusErrCallback = [errorOccurred,
                                             waitingForLoadingData]() {
        --(*waitingForLoadingData);
        *errorOccurred = true;
    };

    boot_time_utils::GetBootTimeDurations(asyncResp, "bmc", bmcDurations,
                                          dbusSuccessCallback, dbusErrCallback);
    boot_time_utils::GetBootTimeCheckpoints(
        asyncResp, "bmc", bmcCheckpoints, dbusSuccessCallback, dbusErrCallback);
    boot_time_utils::GetIsRebooting(asyncResp, "bmc", bmcIsRebooting,
                                    dbusSuccessCallback, dbusErrCallback);
}

inline void requestRoutesBmcBootTime(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Oem/Google/BootTime/")
        .privileges(redfish::privileges::getManager)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleBmcBootTimeDataGet, std::ref(app)));
}
} // namespace redfish
