/*
// 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 "utils/boot_time_utils.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/json_utils.hpp"
#include "utils/sw_utils.hpp"
#include "utils/systemd_utils.hpp"
#include "utils/time_utils.hpp"

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

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

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

namespace redfish
{

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

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

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

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

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

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

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

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

    std::string resetType;

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

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

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

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

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

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

    std::string resetType;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                std::string name;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                    controller["Direction"] = *classPtr;
                }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return nullptr;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        if (chassisContainer)
        {

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

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

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

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

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

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

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

    {}

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

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

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

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

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

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

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

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

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

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

                        calledConnections.insert(connectionGroup.first);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    managerGetLastResetTime(asyncResp);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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