/*
// 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 "chassis.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 "boottime.hpp"
#include "dbus_utils.hpp"
#include "json_utils.hpp"
#include "sw_utils.hpp"
#include "systemd_utils.hpp"
#include "time_utils.hpp"
#include "location_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 <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";

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

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

#ifdef BMCWEB_ENABLE_REDFISH_BOOT_TIME
    auto status = boottime::PopulateBmcData(asyncResp);
    if (!status.ok())
    {
        BMCWEB_LOG_ERROR << status.message();
        messages::resourceMissingAtURI(asyncResp->res,
                                       "redfish/v1/Managers/bmc");
        return;
    }
#else
    messages::serviceDisabled(asyncResp->res, "bmc");
#endif
}

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
