#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_MANAGERS_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_MANAGERS_H_

/*
// 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.
*/

#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <variant>
#include <vector>

#include "absl/strings/str_cat.h"
#include "boost/container/flat_set.hpp"  // NOLINT
#include "boost/system/error_code.hpp"  // NOLINT
#include "app.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "persistent_data.hpp"
#include "error_messages.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "boottime.hpp"
#include "dbus_utils.hpp"
#include "json_utils.hpp"
#include "location_utils.hpp"
#include "sw_utils.hpp"
#include "system_utils.hpp"
#include "systemd_utils.hpp"
#include "time_utils.hpp"
#include "chassis.hpp"
#include "health.hpp"
#include "redfish_util.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/unpack_properties.hpp"

#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;
            } else if (intfPair.first == pidConfigurationIface) {
              // pid and fans are off the same configuration
              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));
                  }
                } else if (propertyPair.first == "Inputs" ||
                           propertyPair.first == "Outputs") {
                  // 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
                  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;
                  }
                } 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") {  // doubles
                  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

  system_utils::getAllSystems(
      asyncResp,
      [](const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
         const dbus::utility::MapperGetSubTreePathsResponse& objects) {
        nlohmann::json::array_t managerForServers;

        if (objects.size() == 1) {
          nlohmann::json::object_t system;
          system["@odata.id"] = "/redfish/v1/Systems/system";
          managerForServers.push_back(std::move(system));
        } else {
          for (const std::string& object : objects) {
            nlohmann::json::object_t system;
            system["@odata.id"] = absl::StrCat(
                "/redfish/v1/Systems", object.substr(object.rfind('/')));
            managerForServers.push_back(std::move(system));
          }
        }

        asyncResp->res.jsonValue["Links"]["ManagerForServers@odata.count"] =
            objects.size();
        asyncResp->res.jsonValue["Links"]["ManagerForServers"] =
            std::move(managerForServers);
      });

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

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

  managerGetLastResetTime(asyncResp);

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

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

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

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

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

  static bool started = false;
  asyncResp->res.jsonValue["Location"]["PartLocation"]["LocationType"] =
      "Embedded";

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#ifdef BMCWEB_ENABLE_REDFISH_BOOT_TIME
  auto status = boottime::PopulateBmcData(asyncResp);
  if (!status.ok()) {
    BMCWEB_LOG_ERROR << status.message();
    messages::internalError(asyncResp->res);
    return;
  }
#else
  std::string oDataId = "/redfish/v1/Managers/bmc/Oem/Google/BootTime";
  boottime::PopulateDisabledResponse(asyncResp, oDataId);
#endif
}

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

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_MANAGERS_H_
