#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_SYSTEMS_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_SYSTEMS_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 <array>
#include <charconv>
#include <chrono>  // NOLINT
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <filesystem>  // NOLINT
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <memory>
#include <optional>
#include <ratio>  // NOLINT
#include <span>   // NOLINT
#include <sstream>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT
#include <tuple>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "boost/container/flat_map.hpp"  // NOLINT
#include "boost/system/error_code.hpp"  // NOLINT
#include "bm_config.h"
#include "bmcweb_config.h"
#include "app.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "dbus_utility.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 "sw_utils.hpp"
#include "system_utils.hpp"
#include "time_utils.hpp"
#include "health.hpp"
#include "led.hpp"
#include "pcie.hpp"
#include "redfish_util.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message/native_types.hpp"
#include "sdbusplus/unpack_properties.hpp"

namespace redfish {

static const std::array<std::pair<std::string_view, std::string_view>, 2>
    protocolToDBusForSystems{
        {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};

constexpr std::array<std::string_view, 1> systemInterfaces{
    {"xyz.openbmc_project.Inventory.Item.System"}};

constexpr std::array<std::string_view, 1> hostStateInterfaces{
    {"xyz.openbmc_project.State.Host"}};

constexpr std::array<std::string_view, 1> chassisStateInterfaces{
    {"xyz.openbmc_project.State.Chassis"}};

/**
 * @brief Updates the Functional State of DIMMs
 *
 * @param[in] aResp Shared pointer for completing asynchronous calls
 * @param[in] dimmState Dimm's Functional state, true/false
 *
 * @return None.
 */
inline void updateDimmProperties(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, bool isDimmFunctional) {
  BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;

  // Set it as Enabled if at least one DIMM is functional
  // Update STATE only if previous State was DISABLED and current Dimm is
  // ENABLED.
  const nlohmann::json& prevMemSummary =
      aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
  if (prevMemSummary == "Disabled") {
    if (isDimmFunctional) {
      aResp->res.jsonValue["MemorySummary"]["Status"]["State"] = "Enabled";
    }
  }
}

/*
 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
 *
 * @param[in] aResp Shared pointer for completing asynchronous calls
 * @param[in] cpuPresenceState CPU present or not
 *
 * @return None.
 */
inline void modifyCpuPresenceState(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, bool isCpuPresent) {
  BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;

  if (isCpuPresent) {
    nlohmann::json& procCount =
        aResp->res.jsonValue["ProcessorSummary"]["Count"];
    auto* procCountPtr = procCount.get_ptr<nlohmann::json::number_integer_t*>();
    if (procCountPtr != nullptr) {
      // shouldn't be possible to be nullptr
      *procCountPtr += 1;
    }
  }
}

/*
 * @brief Update "ProcessorSummary" "Status" "State" based on
 *        CPU Functional State
 *
 * @param[in] aResp Shared pointer for completing asynchronous calls
 * @param[in] cpuFunctionalState is CPU functional true/false
 *
 * @return None.
 */
inline void modifyCpuFunctionalState(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, bool isCpuFunctional) {
  BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;

  const nlohmann::json& prevProcState =
      aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];

  // Set it as Enabled if at least one CPU is functional
  // Update STATE only if previous State was Non_Functional and current CPU is
  // Functional.
  if (prevProcState == "Disabled") {
    if (isCpuFunctional) {
      aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Enabled";
    }
  }
}

inline void getProcessorProperties(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
        properties) {
  BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";

  // TODO: Get Model

  const uint16_t* coreCount = nullptr;

  const bool success = sdbusplus::unpackPropertiesNoThrow(
      dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);

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

  if (coreCount != nullptr) {
    nlohmann::json& coreCountJson =
        aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
    uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();

    if (coreCountJsonPtr == nullptr) {
      coreCountJson = *coreCount;
    } else {
      *coreCountJsonPtr += *coreCount;
    }
  }
}

/*
 * @brief Get ProcessorSummary fields
 *
 * @param[in] aResp Shared pointer for completing asynchronous calls
 * @param[in] service dbus service for Cpu Information
 * @param[in] path dbus path for Cpu
 *
 * @return None.
 */
inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                                const std::string& service,
                                const std::string& path) {
  auto getCpuPresenceState = [aResp](const boost::system::error_code& ec3,
                                     const bool cpuPresenceCheck) {
    if (ec3) {
      BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
      return;
    }
    modifyCpuPresenceState(aResp, cpuPresenceCheck);
  };

  auto getCpuFunctionalState = [aResp](const boost::system::error_code& ec3,
                                       const bool cpuFunctionalCheck) {
    if (ec3) {
      BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
      return;
    }
    modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
  };

  managedStore::ManagedObjectStoreContext context(aResp);

  // Get the Presence of CPU
  dbus_utils::getProperty<bool>(service, path,
                                "xyz.openbmc_project.Inventory.Item", "Present",
                                context, std::move(getCpuPresenceState));

  // Get the Functional State
  dbus_utils::getProperty<bool>(
      service, path, "xyz.openbmc_project.State.Decorator.OperationalStatus",
      "Functional", context, std::move(getCpuFunctionalState));

  managedStore::GetManagedObjectStore()->getAllProperties(
      service, path, "xyz.openbmc_project.Inventory.Item.Cpu", context,
      [aResp, service, path](
          const boost::system::error_code& ec2,
          const dbus::utility::DBusPropertiesMap& properties) {
        if (ec2) {
          BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
          messages::internalError(aResp->res);
          return;
        }
        getProcessorProperties(aResp, properties);
      });
}

/*
 * @brief Retrieves computer system properties over dbus
 *
 * @param[in] aResp Shared pointer for completing asynchronous calls
 * @param[in] systemHealth  Shared HealthPopulate pointer
 *
 * @return None.
 */
inline void getComputerSystem(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::shared_ptr<HealthPopulate>& systemHealth,
    const std::string& systemName) {
  BMCWEB_LOG_DEBUG << "Get available system components.";
  constexpr std::array<std::string_view, 5> interfaces = {
      "xyz.openbmc_project.Inventory.Decorator.Asset",
      "xyz.openbmc_project.Inventory.Item.Cpu",
      "xyz.openbmc_project.Inventory.Item.Dimm",
      "xyz.openbmc_project.Inventory.Item.System",
      "xyz.openbmc_project.Common.UUID",
  };

  managedStore::ManagedObjectStoreContext context(aResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/xyz/openbmc_project/inventory", 0, interfaces, context,
      [aResp, systemHealth, context, systemName](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error";
          messages::internalError(aResp->res);
          return;
        }
        // Iterate over all retrieved ObjectPaths.
        for (const std::pair<
                 std::string,
                 std::vector<std::pair<std::string, std::vector<std::string>>>>&
                 object : subtree) {
          const std::string& path = object.first;
          BMCWEB_LOG_DEBUG << "Got path: " << path;
          const std::vector<std::pair<std::string, std::vector<std::string>>>&
              connectionNames = object.second;
          if (connectionNames.empty()) {
            continue;
          }

          auto memoryHealth = std::make_shared<HealthPopulate>(
              aResp, "/MemorySummary/Status"_json_pointer);

          auto cpuHealth = std::make_shared<HealthPopulate>(
              aResp, "/ProcessorSummary/Status"_json_pointer);

#ifdef HEALTH_POPULATE
          systemHealth->children.emplace_back(memoryHealth);
          systemHealth->children.emplace_back(cpuHealth);
#endif
          // This is not system, so check if it's cpu, dimm, UUID or
          // BiosVer
          const auto& connection =
              connectionNames[0];  // connectionNames not empty, so safe to
                                   // access [0]
          for (const auto& interfaceName : connection.second) {
            if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm") {
              BMCWEB_LOG_DEBUG << "Found Dimm, now get its properties.";

              managedStore::GetManagedObjectStore()->getAllProperties(
                  connection.first, path,
                  "xyz.openbmc_project.Inventory.Item.Dimm", context,
                  [aResp, service{connection.first}, path, context](
                      const boost::system::error_code& ec2,
                      const dbus::utility::DBusPropertiesMap& properties) {
                    if (ec2) {
                      BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
                      messages::internalError(aResp->res);
                      return;
                    }
                    BMCWEB_LOG_DEBUG << "Got " << properties.size()
                                     << " Dimm properties.";

                    if (properties.empty()) {
                      dbus_utils::getProperty<bool>(
                          service, path,
                          "xyz.openbmc_project.State."
                          "Decorator.OperationalStatus",
                          "Functional", context,
                          [aResp](const boost::system::error_code& ec3,
                                  bool dimmState) {
                            if (ec3) {
                              BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
                              return;
                            }
                            updateDimmProperties(aResp, dimmState);
                          });
                      return;
                    }

                    const size_t* memorySizeInKB = nullptr;

                    const bool success = sdbusplus::unpackPropertiesNoThrow(
                        dbus_utils::UnpackErrorPrinter(), properties,
                        "MemorySizeInKB", memorySizeInKB);

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

                    if (memorySizeInKB != nullptr) {
                      nlohmann::json& totalMemory =
                          aResp->res.jsonValue["MemorySummary"]
                                              ["TotalSystemMemoryGiB"];
                      const uint64_t* preValue =
                          totalMemory.get_ptr<const uint64_t*>();
                      if (preValue == nullptr) {
                        aResp->res.jsonValue["MemorySummary"]
                                            ["TotalSystemMemoryGiB"] =
                            *memorySizeInKB / static_cast<size_t>(1024 * 1024);
                      } else {
                        aResp->res.jsonValue["MemorySummary"]
                                            ["TotalSystemMemoryGiB"] =
                            *memorySizeInKB / static_cast<size_t>(1024 * 1024) +
                            *preValue;
                      }
                      aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
                          "Enabled";
                    }
                  });

              memoryHealth->inventory.emplace_back(path);
            } else if (interfaceName ==
                       "xyz.openbmc_project.Inventory.Item.Cpu") {
              BMCWEB_LOG_DEBUG << "Found Cpu, now get its properties.";

              getProcessorSummary(aResp, connection.first, path);

              cpuHealth->inventory.emplace_back(path);
            } else if (interfaceName == "xyz.openbmc_project.Common.UUID") {
              BMCWEB_LOG_DEBUG << "Found UUID, now get its properties.";

              managedStore::GetManagedObjectStore()->getAllProperties(
                  connection.first, path, "xyz.openbmc_project.Common.UUID",
                  context,
                  [aResp](const boost::system::error_code& ec3,
                          const dbus::utility::DBusPropertiesMap& properties) {
                    if (ec3) {
                      BMCWEB_LOG_DEBUG << "DBUS response error " << ec3;
                      messages::internalError(aResp->res);
                      return;
                    }
                    BMCWEB_LOG_DEBUG << "Got " << properties.size()
                                     << " UUID properties.";

                    const std::string* uUID = nullptr;

                    const bool success = sdbusplus::unpackPropertiesNoThrow(
                        dbus_utils::UnpackErrorPrinter(), properties, "UUID",
                        uUID);

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

                    if (uUID != nullptr) {
                      std::string valueStr = *uUID;
                      if (valueStr.size() == 32) {
                        valueStr.insert(8, 1, '-');
                        valueStr.insert(13, 1, '-');
                        valueStr.insert(18, 1, '-');
                        valueStr.insert(23, 1, '-');
                      }
                      BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
                      aResp->res.jsonValue["UUID"] = valueStr;
                    }
                  });
            } else if (interfaceName ==
                       "xyz.openbmc_project.Inventory.Item.System") {
              managedStore::GetManagedObjectStore()->getAllProperties(
                  connection.first, path,
                  "xyz.openbmc_project.Inventory.Decorator.Asset", context,
                  [aResp, context, systemName](
                      const boost::system::error_code& ec2,
                      const dbus::utility::DBusPropertiesMap& propertiesList) {
                    if (ec2) {
                      // doesn't have to include this
                      // interface
                      return;
                    }
                    BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
                                     << " properties for system";

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

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

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

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

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

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

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

                    if (subModel != nullptr) {
                      aResp->res.jsonValue["SubModel"] = *subModel;
                    }

                    // Grab the bios version
                    sw_util::populateSoftwareInformation(
                        aResp, sw_util::biosPurpose, "BiosVersion", false,
                        sw_util::SwAssociation::System, systemName);
                  });

              dbus_utils::getProperty<std::string>(
                  connection.first, path,
                  "xyz.openbmc_project.Inventory.Decorator."
                  "AssetTag",
                  "AssetTag", context,
                  [aResp](const boost::system::error_code& ec2,
                          const std::string& value) {
                    if (ec2) {
                      // doesn't have to include this
                      // interface
                      return;
                    }

                    aResp->res.jsonValue["AssetTag"] = value;
                  });
            }
          }
        }
      });
}

inline void populateHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                              const std::string& service,
                              const std::string& path) {
  managedStore::ManagedObjectStoreContext context(aResp);
  dbus_utils::getProperty<std::string>(
      service, path, "xyz.openbmc_project.State.Host", "CurrentHostState",
      context,
      [aResp](const boost::system::error_code& ec,
              const std::string& hostState) {
        if (ec) {
          if (ec == boost::system::errc::host_unreachable) {
            // Service not available, no error, just don't return
            // host state info
            BMCWEB_LOG_DEBUG << "Service not available " << ec;
            return;
          }
          BMCWEB_LOG_ERROR << "DBUS response error " << ec;
          messages::internalError(aResp->res);
          return;
        }

        BMCWEB_LOG_DEBUG << "Host state: " << hostState;
        // Verify Host State
        if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") {
          aResp->res.jsonValue["PowerState"] = "On";
          aResp->res.jsonValue["Status"]["State"] = "Enabled";
        } else if (hostState ==
                   "xyz.openbmc_project.State.Host.HostState.Quiesced") {
          aResp->res.jsonValue["PowerState"] = "On";
          aResp->res.jsonValue["Status"]["State"] = "Quiesced";
        } else if (hostState ==
                   "xyz.openbmc_project.State.Host.HostState.DiagnosticMode") {
          aResp->res.jsonValue["PowerState"] = "On";
          aResp->res.jsonValue["Status"]["State"] = "InTest";
        } else if (hostState ==
                   "xyz.openbmc_project.State.Host.HostState."
                   "TransitioningToRunning") {
          aResp->res.jsonValue["PowerState"] = "PoweringOn";
          aResp->res.jsonValue["Status"]["State"] = "Starting";
        } else if (hostState ==
                   "xyz.openbmc_project.State.Host.HostState."
                   "TransitioningToOff") {
          aResp->res.jsonValue["PowerState"] = "PoweringOff";
          aResp->res.jsonValue["Status"]["State"] = "Disabled";
        } else {
          aResp->res.jsonValue["PowerState"] = "Off";
          aResp->res.jsonValue["Status"]["State"] = "Disabled";
        }
      });
}

/**
 * @brief Retrieves host state properties over dbus
 *
 * @param[in] aResp     Shared pointer for completing asynchronous calls.
 *
 * @return None.
 */
inline void getHostState(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& systemPath,
    const dbus::utility::MapperGetSubTreeResponse& objects) {
  BMCWEB_LOG_DEBUG << "Get host information.";

  // For single host systems, the path is hardcoded to be
  // /xyz/openbmc_project/state/host0 and the service is
  // xyz.openbmc_project.State.Host
  if (systemPath.empty()) {
    populateHostState(aResp, "xyz.openbmc_project.State.Host",
                      "/xyz/openbmc_project/state/host0");
    return;
  }

  // Objects should never be empty in a multi-host system
  if (objects.empty()) {
    BMCWEB_LOG_ERROR << "Host has no Power Control Objects";
    // Don't return error since there may be no x86-power-control.
    aResp->res.jsonValue["PowerState"] = "Unknown";
    aResp->res.jsonValue["Status"]["State"] = "Unknown";
    return;
  }

  // Map1: [key, val] -> [objectPath, Map2]
  // Map2: [key, val] -> [serviceName, list of interfaces]
  const std::string powerControlPath = objects[0].first;

  // This object path can have multiple services, we need the one that
  // contains "State.Host"
  for (const auto& serviceMapping : objects[0].second) {
    if (absl::StrContains(serviceMapping.first, "State.Host")) {
      populateHostState(aResp, serviceMapping.first, powerControlPath);
      return;
    }
  }

  BMCWEB_LOG_ERROR << "Could not find correct host Power Control Object";
  messages::internalError(aResp->res);
}

/**
 * @brief Translates boot source DBUS property value to redfish.
 *
 * @param[in] dbusSource    The boot source in DBUS speak.
 *
 * @return Returns as a string, the boot source in Redfish terms. If translation
 * cannot be done, returns an empty string.
 */
inline std::string dbusToRfBootSource(const std::string& dbusSource) {
  if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default") {
    return "None";
  }
  if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk") {
    return "Hdd";
  }
  if (dbusSource ==
      "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia") {
    return "Cd";
  }
  if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network") {
    return "Pxe";
  }
  if (dbusSource ==
      "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia") {
    return "Usb";
  }
  return "";
}

/**
 * @brief Translates boot type DBUS property value to redfish.
 *
 * @param[in] dbusType    The boot type in DBUS speak.
 *
 * @return Returns as a string, the boot type in Redfish terms. If translation
 * cannot be done, returns an empty string.
 */
inline std::string dbusToRfBootType(const std::string& dbusType) {
  if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy") {
    return "Legacy";
  }
  if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI") {
    return "UEFI";
  }
  return "";
}

/**
 * @brief Translates boot mode DBUS property value to redfish.
 *
 * @param[in] dbusMode    The boot mode in DBUS speak.
 *
 * @return Returns as a string, the boot mode in Redfish terms. If translation
 * cannot be done, returns an empty string.
 */
inline std::string dbusToRfBootMode(const std::string& dbusMode) {
  if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") {
    return "None";
  }
  if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe") {
    return "Diags";
  }
  if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup") {
    return "BiosSetup";
  }
  return "";
}

/**
 * @brief Translates boot progress DBUS property value to redfish.
 *
 * @param[in] dbusBootProgress    The boot progress in DBUS speak.
 *
 * @return Returns as a string, the boot progress in Redfish terms. If
 *         translation cannot be done, returns "None".
 */
inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress) {
  // Now convert the D-Bus BootProgress to the appropriate Redfish
  // enum
  std::string rfBpLastState = "None";
  if (dbusBootProgress ==
      "xyz.openbmc_project.State.Boot.Progress."
      "ProgressStages.Unspecified") {
    rfBpLastState = "None";
  } else if (dbusBootProgress ==
             "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
             "PrimaryProcInit") {
    rfBpLastState = "PrimaryProcessorInitializationStarted";
  } else if (dbusBootProgress ==
             "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
             "BusInit") {
    rfBpLastState = "BusInitializationStarted";
  } else if (dbusBootProgress ==
             "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
             "MemoryInit") {
    rfBpLastState = "MemoryInitializationStarted";
  } else if (dbusBootProgress ==
             "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
             "SecondaryProcInit") {
    rfBpLastState = "SecondaryProcessorInitializationStarted";
  } else if (dbusBootProgress ==
             "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
             "PCIInit") {
    rfBpLastState = "PCIResourceConfigStarted";
  } else if (dbusBootProgress ==
             "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
             "SystemSetup") {
    rfBpLastState = "SetupEntered";
  } else if (dbusBootProgress ==
             "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
             "SystemInitComplete") {
    rfBpLastState = "SystemHardwareInitializationComplete";
  } else if (dbusBootProgress ==
             "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
             "OSStart") {
    rfBpLastState = "OSBootStarted";
  } else if (dbusBootProgress ==
             "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
             "OSRunning") {
    rfBpLastState = "OSRunning";
  } else if (dbusBootProgress ==
             "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
             "OEM") {
    rfBpLastState = "OEM";
  } else {
    BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress " << dbusBootProgress;
    // Just return the default
  }
  return rfBpLastState;
}

/**
 * @brief Translates boot source from Redfish to the DBus boot paths.
 *
 * @param[in] rfSource    The boot source in Redfish.
 * @param[out] bootSource The DBus source
 * @param[out] bootMode   the DBus boot mode
 *
 * @return Integer error code.
 */
inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                                const std::string& rfSource,
                                std::string& bootSource,
                                std::string& bootMode) {
  bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
  bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";

  if (rfSource == "None") {
    return 0;
  }
  if (rfSource == "Pxe") {
    bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
  } else if (rfSource == "Hdd") {
    bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
  } else if (rfSource == "Diags") {
    bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
  } else if (rfSource == "Cd") {
    bootSource =
        "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
  } else if (rfSource == "BiosSetup") {
    bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
  } else if (rfSource == "Usb") {
    bootSource =
        "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
  } else {
    BMCWEB_LOG_DEBUG << "Invalid property value for BootSourceOverrideTarget: "
                     << bootSource;
    messages::propertyValueNotInList(aResp->res, rfSource,
                                     "BootSourceTargetOverride");
    return -1;
  }
  return 0;
}

/**
 * @brief Retrieves boot progress of the system
 *
 * @param[in] aResp  Shared pointer for generating response message.
 *
 * @return None.
 */
inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  managedStore::ManagedObjectStoreContext context(aResp);
  dbus_utils::getProperty<std::string>(
      "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
      "xyz.openbmc_project.State.Boot.Progress", "BootProgress", context,
      [aResp](const boost::system::error_code& ec,
              const std::string& bootProgressStr) {
        if (ec) {
          // BootProgress is an optional object so just do nothing if
          // not found
          return;
        }

        BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;

        aResp->res.jsonValue["BootProgress"]["LastState"] =
            dbusToRfBootProgress(bootProgressStr);
      });
}

/**
 * @brief Retrieves boot progress Last Update of the system
 *
 * @param[in] aResp  Shared pointer for generating response message.
 *
 * @return None.
 */
inline void getBootProgressLastStateTime(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  managedStore::ManagedObjectStoreContext context(aResp);
  dbus_utils::getProperty<uint64_t>(
      "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
      "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
      context,
      [aResp](const boost::system::error_code& ec,
              const uint64_t lastStateTime) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
          return;
        }

        // BootProgressLastUpdate is the last time the BootProgress property
        // was updated. The time is the Epoch time, number of microseconds
        // since 1 Jan 1970 00::00::00 UTC."
        // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
        // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11

        // Convert to ISO 8601 standard
        aResp->res.jsonValue["BootProgress"]["LastStateTime"] =
            redfish::time_utils::getDateTimeUintUs(lastStateTime);
      });
}

/**
 * @brief Retrieves boot progress OemLastState of the system
 *
 * @param[in] aResp  Shared pointer for generating response message.
 *
 * @return None.
 */
inline void getBootProgressOemLastState(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  /* Check the boot progress LastState */
  managedStore::ManagedObjectStoreContext requestContext(aResp);
  dbus_utils::getProperty<std::string>(
      "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
      "xyz.openbmc_project.State.Boot.Progress", "BootProgress", requestContext,
      [aResp, requestContext](const boost::system::error_code ec,
                              const std::string& bootProgressStr) {
        if (ec) {
          // BootProgress is an optional object so just do nothing if
          // not found
          return;
        }
        /* The OemLastState only present if LastState is "OEM" */
        if (dbusToRfBootProgress(bootProgressStr) == "OEM") {
          // TODO: Move to dbus_utils::getProperty once tuple support is added
          // b/293925308
          dbus_utils::getProperty<std::tuple<uint64_t, std::vector<uint8_t>>>(
              "xyz.openbmc_project.State.Boot.Raw",
              "/xyz/openbmc_project/state/boot/raw0",
              "xyz.openbmc_project.State.Boot.Raw", "Value", requestContext,
              [aResp](const boost::system::error_code ec2,
                      const std::tuple<uint64_t, std::vector<uint8_t>>&
                          bootProgressOemLastState) {
                if (ec2) {
                  return;
                }

                std::string bootProgressOemLastStateStr = "0x";
                std::stringstream tmp;
                uint64_t bootProgress1st = 0;
                std::vector<uint8_t> bootProgress2nd;

                /* The OemLastState updated to the PostCodes Boot.Raw:
                 * https://github.com/openbmc/phosphor-dbus-interfaces/blob/
                 * master/yaml/xyz/openbmc_project/State/Boot/Raw.interface.yaml#L6
                 * The type of the Boot.Raw value is struct[uint64,array[byte]]
                 */
                bootProgress1st = std::get<0>(bootProgressOemLastState);
                bootProgress2nd = std::get<1>(bootProgressOemLastState);
                /* Formatting boot progress code */
                tmp << std::hex << std::setfill('0');

                /* Set "OemLastState": to "" if there is no bootprogress code */
                if (bootProgress1st == 0) {
                  bootProgressOemLastStateStr = "";
                } else {
                  /* Get first bytes of the boot progress code */
                  tmp << std::setw(2) << static_cast<uint64_t>(bootProgress1st);

                  if (!bootProgress2nd.empty()) {
                    /* Get the last byte of the boot progress code */
                    for (uint8_t i : bootProgress2nd) {
                      tmp << std::setw(2) << static_cast<uint16_t>(i);
                    }
                  }
                  /* Padding, Ex: 0x1020304 to 0x01020304 */
                  if ((tmp.str().size() % 2) != 0) {
                    bootProgressOemLastStateStr = "0x0";
                  }
                  bootProgressOemLastStateStr += tmp.str();
                }

                aResp->res.jsonValue["BootProgress"]["OemLastState"] =
                    bootProgressOemLastStateStr;
              });
        }
      });
}

/**
 * @brief Retrieves boot override type over DBUS and fills out the response
 *
 * @param[in] aResp         Shared pointer for generating response message.
 *
 * @return None.
 */

inline void getBootOverrideType(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  managedStore::ManagedObjectStoreContext context(aResp);
  dbus_utils::getProperty<std::string>(
      "xyz.openbmc_project.Settings", "/xyz/openbmc_project/control/host0/boot",
      "xyz.openbmc_project.Control.Boot.Type", "BootType", context,
      [aResp](const boost::system::error_code& ec,
              const std::string& bootType) {
        if (ec) {
          // not an error, don't have to have the interface
          return;
        }

        BMCWEB_LOG_DEBUG << "Boot type: " << bootType;

        aResp->res.jsonValue["Boot"]
                            ["BootSourceOverrideMode@Redfish.AllowableValues"] =
            nlohmann::json::array_t({"Legacy", "UEFI"});

        auto rfType = dbusToRfBootType(bootType);
        if (rfType.empty()) {
          messages::internalError(aResp->res);
          return;
        }

        aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
      });
}

/**
 * @brief Retrieves boot override mode over DBUS and fills out the response
 *
 * @param[in] aResp         Shared pointer for generating response message.
 *
 * @return None.
 */

inline void getBootOverrideMode(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  managedStore::ManagedObjectStoreContext context(aResp);
  dbus_utils::getProperty<std::string>(
      "xyz.openbmc_project.Settings", "/xyz/openbmc_project/control/host0/boot",
      "xyz.openbmc_project.Control.Boot.Mode", "BootMode", context,
      [aResp](const boost::system::error_code& ec,
              const std::string& bootModeStr) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
          messages::internalError(aResp->res);
          return;
        }

        BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;

        aResp->res
            .jsonValue["Boot"]
                      ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
            "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};

        if (bootModeStr !=
            "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular") {
          auto rfMode = dbusToRfBootMode(bootModeStr);
          if (!rfMode.empty()) {
            aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode;
          }
        }
      });
}

/**
 * @brief Retrieves boot override source over DBUS
 *
 * @param[in] aResp         Shared pointer for generating response message.
 *
 * @return None.
 */

inline void getBootOverrideSource(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  managedStore::ManagedObjectStoreContext context(aResp);
  dbus_utils::getProperty<std::string>(
      "xyz.openbmc_project.Settings", "/xyz/openbmc_project/control/host0/boot",
      "xyz.openbmc_project.Control.Boot.Source", "BootSource", context,
      [aResp](const boost::system::error_code& ec,
              const std::string& bootSourceStr) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
          if (ec.value() == boost::asio::error::host_unreachable) {
            return;
          }
          messages::internalError(aResp->res);
          return;
        }

        BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;

        auto rfSource = dbusToRfBootSource(bootSourceStr);
        if (!rfSource.empty()) {
          aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource;
        }

        // Get BootMode as BootSourceOverrideTarget is constructed
        // from both BootSource and BootMode
        getBootOverrideMode(aResp);
      });
}

/**
 * @brief This functions abstracts all the logic behind getting a
 * "BootSourceOverrideEnabled" property from an overall boot override enable
 * state
 *
 * @param[in] aResp     Shared pointer for generating response message.
 *
 * @return None.
 */

inline void processBootOverrideEnable(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const bool bootOverrideEnableSetting) {
  if (!bootOverrideEnableSetting) {
    aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
    return;
  }

  // If boot source override is enabled, we need to check 'one_time'
  // property to set a correct value for the "BootSourceOverrideEnabled"
  managedStore::ManagedObjectStoreContext context(aResp);
  dbus_utils::getProperty<bool>(
      "xyz.openbmc_project.Settings",
      "/xyz/openbmc_project/control/host0/boot/one_time",
      "xyz.openbmc_project.Object.Enable", "Enabled", context,
      [aResp](const boost::system::error_code& ec, bool oneTimeSetting) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
          messages::internalError(aResp->res);
          return;
        }

        if (oneTimeSetting) {
          aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once";
        } else {
          aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
              "Continuous";
        }
      });
}

/**
 * @brief Retrieves boot override enable over DBUS
 *
 * @param[in] aResp     Shared pointer for generating response message.
 *
 * @return None.
 */

inline void getBootOverrideEnable(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  managedStore::ManagedObjectStoreContext context(aResp);
  dbus_utils::getProperty<bool>(
      "xyz.openbmc_project.Settings", "/xyz/openbmc_project/control/host0/boot",
      "xyz.openbmc_project.Object.Enable", "Enabled", context,
      [aResp](const boost::system::error_code& ec,
              const bool bootOverrideEnable) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
          if (ec.value() == boost::asio::error::host_unreachable) {
            return;
          }
          messages::internalError(aResp->res);
          return;
        }

        processBootOverrideEnable(aResp, bootOverrideEnable);
      });
}

/**
 * @brief Retrieves mapping of systemName to its BIOS setting file path.
 *
 * @param[in] systemName The name of the system (e.g. "system", "system1",
 * "system2").
 *
 * @return The BIOS setting file path as a string.
 */
inline absl::StatusOr<std::string> getBiosSettingPath(
    const std::string& systemName) {
  // Legacy oem_bios_setting file paths are for single host machines.
  if (systemName == "system") {
    return "/var/google/oem_bios_setting";
  }
  if (systemName == "system1") {
    return "/var/google/system1/oem_bios_setting";
  }
  if (systemName == "system2") {
    return "/var/google/system2/oem_bios_setting";
  }
  return absl::InvalidArgumentError(absl::StrCat(
      "BIOS setting path not found: unsupported system: ", systemName));
}

/**
 * @brief Retrieves boot order from oem_bios_setting file
 *
 * @param[in] aResp     Shared pointer for generating response message.
 *
 * @return None.
 */
inline void getBootOrder(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                         const std::string& biosSettingFile) {
  std::ifstream file(biosSettingFile, std::ios::binary | std::ios::ate);
  if (!file.is_open()) {
    BMCWEB_LOG_DEBUG << biosSettingFile << " not found.";
    return;
  }

  std::streamsize size = file.tellg();
  file.seekg(0, std::ios::beg);

  if (size < 0 || size % 2 != 0) {
    BMCWEB_LOG_ERROR << "Invalid file size for " << biosSettingFile;
    return;
  }

  std::vector<char> buffer(static_cast<size_t>(size));
  if (!file.read(buffer.data(), size)) {
    BMCWEB_LOG_ERROR << "Failed to read " << biosSettingFile;
    return;
  }

  std::vector<std::string> bootOrder;
  for (size_t i = 0; i < buffer.size(); i += 2) {
    // Assuming little-endian as per hexdump example
    uint16_t bootIndex =
        static_cast<uint16_t>((static_cast<uint8_t>(buffer[i + 1]) << 8) |
                              static_cast<uint8_t>(buffer[i]));

    std::stringstream stream;
    stream << "Boot" << std::setw(4) << std::setfill('0') << std::hex
           << std::uppercase << bootIndex;
    bootOrder.push_back(stream.str());
  }

  aResp->res.jsonValue["Boot"]["BootOrder"] = bootOrder;
}

/**
 * @brief Sets boot order to oem-bios-setting file
 *
 * @param[in] aResp     Shared pointer for generating response message.
 * @param[in] bootOrder   The boot order from incoming RF request.
 *
 * @return None.
 */
inline void setBootOrder(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                         const std::vector<std::string>& bootOrder,
                         const std::string& biosSettingFile) {
  // Ensure the parent directory of the setting file exists.
  std::error_code dirEc;
  std::filesystem::path parentDir =
      std::filesystem::path(biosSettingFile).parent_path();
  std::filesystem::create_directories(parentDir, dirEc);
  if (dirEc) {
    BMCWEB_LOG_ERROR << "Failed to create directory " << parentDir.string()
                     << ": " << dirEc.message();
    messages::internalError(aResp->res);
    return;
  }

  // Create a temporary file to ensure atomic write
  std::string tempFile = biosSettingFile + ".tmp";
  std::ofstream file(tempFile, std::ios::binary | std::ios::trunc);
  if (!file.is_open()) {
    BMCWEB_LOG_ERROR << "Failed to open " << tempFile << " for writing.";
    messages::internalError(aResp->res);
    return;
  }

  for (const std::string& bootDevice : bootOrder) {
    if (!bootDevice.starts_with("Boot") || bootDevice.length() <= 4) {
      BMCWEB_LOG_ERROR << "Invalid BootOrder format: " << bootDevice;
      messages::propertyValueFormatError(aResp->res, bootDevice, "BootOrder");
      file.close();
      std::remove(tempFile.c_str());
      return;
    }

    uint16_t bootIndex = 0;
    std::string_view hexPart = bootDevice;
    hexPart.remove_prefix(4);

    auto [ptr, ec] = std::from_chars(
        hexPart.data(), hexPart.data() + hexPart.size(), bootIndex, 16);

    if (ec != std::errc() || ptr != hexPart.data() + hexPart.size()) {
      BMCWEB_LOG_ERROR << "Invalid hex in BootOrder: " << bootDevice;
      messages::propertyValueFormatError(aResp->res, bootDevice, "BootOrder");
      file.close();
      std::remove(tempFile.c_str());
      return;
    }

    // Write as little-endian
    file.write(reinterpret_cast<const char*>(&bootIndex), sizeof(bootIndex));
  }
  file.close();

  // Atomically rename the temporary file to the final destination
  if (std::rename(tempFile.c_str(), biosSettingFile.c_str()) != 0) {
    BMCWEB_LOG_ERROR << "Failed to rename " << tempFile << " to "
                     << biosSettingFile;
    messages::internalError(aResp->res);
    std::remove(tempFile.c_str());
    return;
  }
}

/**
 * @brief Retrieves boot source override properties
 *
 * @param[in] aResp     Shared pointer for generating response message.
 *
 * @return None.
 */
inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                              const std::string& systemName, bool multiHost) {
  BMCWEB_LOG_DEBUG << "Get boot information.";
  // Only supported for single host

  if (!multiHost) {
    getBootOverrideSource(aResp);
    getBootOverrideType(aResp);
    getBootOverrideEnable(aResp);
  }
  if (std::shared_ptr<milotic_tlbmc::SystemRegistry> registry =
          managedStore::GetManagedObjectStore()->GetSystemRegistry()) {
    absl::StatusOr<std::string> bootNext = registry->GetBootNext(systemName);
    if (bootNext.ok()) {
      aResp->res.jsonValue["Boot"]["BootNext"] = *bootNext;
    } else if (!absl::IsNotFound(bootNext.status())) {
      BMCWEB_LOG_ERROR << "Failed to get BootNext: " << bootNext.status();
    }
  }
  absl::StatusOr<std::string> biosSettingFile = getBiosSettingPath(systemName);
  if (!biosSettingFile.ok()) {
    return;
  }
  getBootOrder(aResp, *biosSettingFile);
}

inline void populateLastResetTime(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, const std::string& service,
    const std::string& path) {
  managedStore::ManagedObjectStoreContext context(aResp);
  dbus_utils::getProperty<uint64_t>(
      service, path, "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
      context,
      [aResp](const boost::system::error_code& ec, uint64_t lastResetTime) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
          return;
        }

        // LastStateChangeTime is epoch time, in milliseconds
        // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
        uint64_t lastResetTimeStamp = lastResetTime / 1000;

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

/**
 * @brief Retrieves the Last Reset Time
 *
 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
 * and power off. Even though this is the "system" Redfish object look at the
 * chassis D-Bus interface for the LastStateChangeTime since this has the
 * last power operation time.
 *
 * @param[in] aResp     Shared pointer for generating response message.
 *
 * @return None.
 */
inline void getLastResetTime(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& systemPath,
    const dbus::utility::MapperGetSubTreeResponse& objects) {
  BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";

  // Single system hardcodes chassis power control object
  if (systemPath.empty()) {
    populateLastResetTime(aResp, "xyz.openbmc_project.State.Chassis",
                          "/xyz/openbmc_project/state/chassis0");
    return;
  }

  // Objects should never be empty in a multi-host system
  if (objects.empty()) {
    BMCWEB_LOG_ERROR << "Host has no Power Control Objects";
    // Do not throw an error since x86-power-control may not be there.
    aResp->res.jsonValue["LastResetTime"] = "Unknown";
    return;
  }

  // Map1: [key, val] -> [objectPath, Map2]
  // Map2: [key, val] -> [serviceName, list of interfaces]
  const std::string powerControlPath = objects[0].first;

  // This object path can have multiple services, we need the one that
  // contains "State.Host"
  for (const auto& serviceMapping : objects[0].second) {
    if (absl::StrContains(serviceMapping.first, "State.Chassis")) {
      populateLastResetTime(aResp, serviceMapping.first, powerControlPath);
      return;
    }
  }

  BMCWEB_LOG_ERROR << "Could not find correct chassis Power Control Object";
  messages::internalError(aResp->res);
}

/**
 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
 *
 * @param[in] aResp     Shared pointer for generating response message.
 *
 * @return None.
 */
inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
  managedStore::ManagedObjectStoreContext context(aResp);
  dbus_utils::getProperty<bool>(
      "xyz.openbmc_project.Settings",
      "/xyz/openbmc_project/control/host0/auto_reboot",
      "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot", context,
      [aResp, context](const boost::system::error_code& ec,
                       bool autoRebootEnabled) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
          return;
        }

        BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
        if (autoRebootEnabled) {
          aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
              "RetryAttempts";
          // If AutomaticRetry (AutoReboot) is enabled see how many
          // attempts are left
          dbus_utils::getProperty<uint32_t>(
              "xyz.openbmc_project.State.Host",
              "/xyz/openbmc_project/state/host0",
              "xyz.openbmc_project.Control.Boot.RebootAttempts", "AttemptsLeft",
              context,
              [aResp](const boost::system::error_code& ec2,
                      const uint32_t autoRebootAttemptsLeft) {
                if (ec2) {
                  BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
                  return;
                }

                BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
                                 << autoRebootAttemptsLeft;

                aResp->res
                    .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
                    autoRebootAttemptsLeft;
              });
        } else {
          aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled";
        }

        // Not on D-Bus. Hardcoded here:
        // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
        aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;

        // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
        // and RetryAttempts. OpenBMC only supports Disabled and
        // RetryAttempts.
        aResp->res.jsonValue["Boot"]
                            ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
            "Disabled", "RetryAttempts"};
      });
}

/**
 * @brief Retrieves power restore policy over DBUS.
 *
 * @param[in] aResp     Shared pointer for generating response message.
 *
 * @return None.
 */
inline void getPowerRestorePolicy(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  BMCWEB_LOG_DEBUG << "Get power restore policy";

  managedStore::ManagedObjectStoreContext context(aResp);
  dbus_utils::getProperty<std::string>(
      "xyz.openbmc_project.Settings",
      "/xyz/openbmc_project/control/host0/power_restore_policy",
      "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
      context,
      [aResp](const boost::system::error_code& ec, const std::string& policy) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
          return;
        }

        const boost::container::flat_map<std::string, std::string> policyMaps =
            {{"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
              "AlwaysOn"},
             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
              "AlwaysOff",
              "AlwaysOff"},
             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
              "LastState"},
             // Return `AlwaysOff` when power restore policy set to "None"
             {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
              "AlwaysOff"}};

        auto policyMapsIt = policyMaps.find(policy);
        if (policyMapsIt == policyMaps.end()) {
          messages::internalError(aResp->res);
          return;
        }

        aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
      });
}

/**
 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
 * TPM is required for booting the host.
 *
 * @param[in] aResp     Shared pointer for generating response message.
 *
 * @return None.
 */
inline void getTrustedModuleRequiredToBoot(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Control.TPM.Policy"};
  managedStore::ManagedObjectStoreContext context(aResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/", 0, interfaces, context,
      [aResp, context](const boost::system::error_code& ec,
                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
                           << ec;
          // This is an optional D-Bus object so just return if
          // error occurs
          return;
        }
        if (subtree.empty()) {
          // As noted above, this is an optional interface so just return
          // if there is no instance found
          return;
        }

        /* When there is more than one TPMEnable object... */
        if (subtree.size() > 1) {
          BMCWEB_LOG_DEBUG << "DBUS response has more than 1 TPM Enable object:"
                           << subtree.size();
          // Throw an internal Error and return
          messages::internalError(aResp->res);
          return;
        }

        // Make sure the Dbus response map has a service and objectPath
        // field
        if (subtree[0].first.empty() || subtree[0].second.size() != 1) {
          BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
          messages::internalError(aResp->res);
          return;
        }

        const std::string& path = subtree[0].first;
        const std::string& serv = subtree[0].second.begin()->first;

        // Valid TPM Enable object found, now reading the current value
        dbus_utils::getProperty<bool>(
            serv, path, "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
            context,
            [aResp](const boost::system::error_code& ec2, bool tpmRequired) {
              if (ec2) {
                BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
                                 << ec2;
                messages::internalError(aResp->res);
                return;
              }

              if (tpmRequired) {
                aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
                    "Required";
              } else {
                aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
                    "Disabled";
              }
            });
      });
}

/**
 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
 * TPM is required for booting the host.
 *
 * @param[in] aResp         Shared pointer for generating response message.
 * @param[in] tpmRequired   Value to set TPM Required To Boot property to.
 *
 * @return None.
 */
inline void setTrustedModuleRequiredToBoot(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired) {
  BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Control.TPM.Policy"};
  managedStore::ManagedObjectStoreContext requestContext(aResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/", 0, interfaces, requestContext,
      [aResp, tpmRequired](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
                           << ec;
          messages::internalError(aResp->res);
          return;
        }
        if (subtree.empty()) {
          messages::propertyValueNotInList(aResp->res, "ComputerSystem",
                                           "TrustedModuleRequiredToBoot");
          return;
        }

        /* When there is more than one TPMEnable object... */
        if (subtree.size() > 1) {
          BMCWEB_LOG_DEBUG << "DBUS response has more than 1 TPM Enable object:"
                           << subtree.size();
          // Throw an internal Error and return
          messages::internalError(aResp->res);
          return;
        }

        // Make sure the Dbus response map has a service and objectPath
        // field
        if (subtree[0].first.empty() || subtree[0].second.size() != 1) {
          BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
          messages::internalError(aResp->res);
          return;
        }

        const std::string& path = subtree[0].first;
        const std::string& serv = subtree[0].second.begin()->first;

        if (serv.empty()) {
          BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
          messages::internalError(aResp->res);
          return;
        }

        // Valid TPM Enable object found, now setting the value
        managedStore::GetManagedObjectStore()
            ->PostDbusCallToIoContextThreadSafe(
                aResp->strand_,
                absl::AnyInvocable<void(const boost::system::error_code&)>(
                    [aResp](const boost::system::error_code& ec2) {
                      if (ec2) {
                        BMCWEB_LOG_DEBUG << "DBUS response error: Set "
                                            "TrustedModuleRequiredToBoot"
                                         << ec2;
                        messages::internalError(aResp->res);
                        return;
                      }
                      BMCWEB_LOG_DEBUG
                          << "Set TrustedModuleRequiredToBoot done.";
                    }),
                serv, path, "org.freedesktop.DBus.Properties", "Set",
                "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
                dbus::utility::DbusVariantType(tpmRequired));
      });
}

/**
 * @brief Sets boot properties into DBUS object(s).
 *
 * @param[in] aResp           Shared pointer for generating response message.
 * @param[in] bootType        The boot type to set.
 * @return Integer error code.
 */
inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                        const std::optional<std::string>& bootType) {
  std::string bootTypeStr;

  if (!bootType) {
    return;
  }

  // Source target specified
  BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
  // Figure out which DBUS interface and property to use
  if (*bootType == "Legacy") {
    bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
  } else if (*bootType == "UEFI") {
    bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
  } else {
    BMCWEB_LOG_DEBUG << "Invalid property value for "
                        "BootSourceOverrideMode: "
                     << *bootType;
    messages::propertyValueNotInList(aResp->res, *bootType,
                                     "BootSourceOverrideMode");
    return;
  }

  // Act on validated parameters
  BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      absl::AnyInvocable<void(const boost::system::error_code&)>(
          [aResp](const boost::system::error_code& ec) {
            if (ec) {
              BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
              if (ec.value() == boost::asio::error::host_unreachable) {
                messages::resourceNotFound(aResp->res, "Set", "BootType");
                return;
              }
              messages::internalError(aResp->res);
              return;
            }
            BMCWEB_LOG_DEBUG << "Boot type update done.";
          }),
      "xyz.openbmc_project.Settings", "/xyz/openbmc_project/control/host0/boot",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Control.Boot.Type", "BootType",
      dbus::utility::DbusVariantType(bootTypeStr));
}

/**
 * @brief Sets boot properties into DBUS object(s).
 *
 * @param[in] aResp           Shared pointer for generating response message.
 * @param[in] bootType        The boot type to set.
 * @return Integer error code.
 */
inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                          const std::optional<std::string>& bootEnable) {
  if (!bootEnable) {
    return;
  }
  // Source target specified
  BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;

  bool bootOverrideEnable = false;
  bool bootOverridePersistent = false;
  // Figure out which DBUS interface and property to use
  if (*bootEnable == "Disabled") {
    bootOverrideEnable = false;
  } else if (*bootEnable == "Once") {
    bootOverrideEnable = true;
    bootOverridePersistent = false;
  } else if (*bootEnable == "Continuous") {
    bootOverrideEnable = true;
    bootOverridePersistent = true;
  } else {
    BMCWEB_LOG_DEBUG << "Invalid property value for BootSourceOverrideEnabled: "
                     << *bootEnable;
    messages::propertyValueNotInList(aResp->res, *bootEnable,
                                     "BootSourceOverrideEnabled");
    return;
  }

  // Act on validated parameters
  BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      absl::AnyInvocable<void(const boost::system::error_code&)>(
          [aResp](const boost::system::error_code& ec2) {
            if (ec2) {
              BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
              messages::internalError(aResp->res);
              return;
            }
            BMCWEB_LOG_DEBUG << "Boot override enable update done.";
          }),
      "xyz.openbmc_project.Settings", "/xyz/openbmc_project/control/host0/boot",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Object.Enable", "Enabled",
      dbus::utility::DbusVariantType(bootOverrideEnable));

  if (!bootOverrideEnable) {
    return;
  }

  // In case boot override is enabled we need to set correct value for the
  // 'one_time' enable DBus interface
  BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
                   << bootOverridePersistent;

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      absl::AnyInvocable<void(const boost::system::error_code&)>(
          [aResp](const boost::system::error_code& ec) {
            if (ec) {
              BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
              messages::internalError(aResp->res);
              return;
            }
            BMCWEB_LOG_DEBUG << "Boot one_time update done.";
          }),
      "xyz.openbmc_project.Settings",
      "/xyz/openbmc_project/control/host0/boot/one_time",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Object.Enable", "Enabled",
      dbus::utility::DbusVariantType(!bootOverridePersistent));
}

/**
 * @brief Sets boot properties into DBUS object(s).
 *
 * @param[in] aResp           Shared pointer for generating response message.
 * @param[in] bootSource      The boot source to set.
 *
 * @return Integer error code.
 */
inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                                const std::optional<std::string>& bootSource) {
  std::string bootSourceStr;
  std::string bootModeStr;

  if (!bootSource) {
    return;
  }

  // Source target specified
  BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
  // Figure out which DBUS interface and property to use
  if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
      0) {
    BMCWEB_LOG_DEBUG << "Invalid property value for BootSourceOverrideTarget: "
                     << *bootSource;
    messages::propertyValueNotInList(aResp->res, *bootSource,
                                     "BootSourceTargetOverride");
    return;
  }

  // Act on validated parameters
  BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
  BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      absl::AnyInvocable<void(const boost::system::error_code&)>(
          [aResp](const boost::system::error_code& ec) {
            if (ec) {
              BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
              messages::internalError(aResp->res);
              return;
            }
            BMCWEB_LOG_DEBUG << "Boot source update done.";
          }),
      "xyz.openbmc_project.Settings", "/xyz/openbmc_project/control/host0/boot",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Control.Boot.Source", "BootSource",
      dbus::utility::DbusVariantType(bootSourceStr));

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      absl::AnyInvocable<void(const boost::system::error_code&)>(
          [aResp](const boost::system::error_code& ec) {
            if (ec) {
              BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
              messages::internalError(aResp->res);
              return;
            }
            BMCWEB_LOG_DEBUG << "Boot mode update done.";
          }),
      "xyz.openbmc_project.Settings", "/xyz/openbmc_project/control/host0/boot",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
      dbus::utility::DbusVariantType(bootModeStr));
}

/**
 * @brief Sets Boot source override properties.
 *
 * @param[in] aResp      Shared pointer for generating response message.
 * @param[in] bootSource The boot source from incoming RF request.
 * @param[in] bootType   The boot type from incoming RF request.
 * @param[in] bootEnable The boot override enable from incoming RF request.
 * @param[in] bootOrder  The boot order from incoming RF request.
 *
 * @return Integer error code.
 */

inline void setBootProperties(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::optional<std::string>& bootSource,
    const std::optional<std::string>& bootType,
    const std::optional<std::string>& bootEnable,
    const std::optional<std::vector<std::string>>& bootOrder,
    const std::string& systemName, bool multiHost) {
  BMCWEB_LOG_DEBUG << "Set boot information.";

  // Only supported in single host
  if (!multiHost) {
    setBootModeOrSource(aResp, bootSource);
    setBootType(aResp, bootType);
    setBootEnable(aResp, bootEnable);
  }

  if (bootOrder) {
    absl::StatusOr<std::string> biosSettingFile =
        getBiosSettingPath(systemName);
    if (!biosSettingFile.ok()) {
      BMCWEB_LOG_ERROR << biosSettingFile.status().message();
      messages::internalError(aResp->res);
      return;
    }
    setBootOrder(aResp, *bootOrder, *biosSettingFile);
  }
}

/**
 * @brief Sets AssetTag
 *
 * @param[in] aResp   Shared pointer for generating response message.
 * @param[in] assetTag  "AssetTag" from request.
 *
 * @return None.
 */
inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                        const std::string& assetTag) {
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Inventory.Item.System"};
  managedStore::ManagedObjectStoreContext requestContext(aResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
      [aResp, assetTag](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
          messages::internalError(aResp->res);
          return;
        }
        if (subtree.empty()) {
          BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
          messages::internalError(aResp->res);
          return;
        }
        // Assume only 1 system D-Bus object
        // Throw an error if there is more than 1
        if (subtree.size() > 1) {
          BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
          messages::internalError(aResp->res);
          return;
        }
        if (subtree[0].first.empty() || subtree[0].second.size() != 1) {
          BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
          messages::internalError(aResp->res);
          return;
        }

        const std::string& path = subtree[0].first;
        const std::string& service = subtree[0].second.begin()->first;

        if (service.empty()) {
          BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
          messages::internalError(aResp->res);
          return;
        }

        managedStore::GetManagedObjectStore()
            ->PostDbusCallToIoContextThreadSafe(
                aResp->strand_,
                absl::AnyInvocable<void(const boost::system::error_code&)>(
                    [aResp](const boost::system::error_code& ec2) {
                      if (ec2) {
                        BMCWEB_LOG_DEBUG
                            << "D-Bus response error on AssetTag Set " << ec2;
                        messages::internalError(aResp->res);
                        return;
                      }
                    }),
                service, path, "org.freedesktop.DBus.Properties", "Set",
                "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
                dbus::utility::DbusVariantType(assetTag));
      });
}

/**
 * @brief Sets automaticRetry (Auto Reboot)
 *
 * @param[in] aResp   Shared pointer for generating response message.
 * @param[in] automaticRetryConfig  "AutomaticRetryConfig" from request.
 *
 * @return None.
 */
inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                              const std::string& automaticRetryConfig) {
  BMCWEB_LOG_DEBUG << "Set Automatic Retry.";

  // OpenBMC only supports "Disabled" and "RetryAttempts".
  bool autoRebootEnabled = false;

  if (automaticRetryConfig == "Disabled") {
    autoRebootEnabled = false;
  } else if (automaticRetryConfig == "RetryAttempts") {
    autoRebootEnabled = true;
  } else {
    BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
                     << automaticRetryConfig;
    messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
                                     "AutomaticRetryConfig");
    return;
  }

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      absl::AnyInvocable<void(const boost::system::error_code&)>(
          [aResp](const boost::system::error_code& ec) {
            if (ec) {
              messages::internalError(aResp->res);
              return;
            }
          }),
      "xyz.openbmc_project.Settings",
      "/xyz/openbmc_project/control/host0/auto_reboot",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
      dbus::utility::DbusVariantType(autoRebootEnabled));
}

/**
 * @brief Sets power restore policy properties.
 *
 * @param[in] aResp   Shared pointer for generating response message.
 * @param[in] policy  power restore policy properties from request.
 *
 * @return None.
 */
inline void setPowerRestorePolicy(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& policy) {
  BMCWEB_LOG_DEBUG << "Set power restore policy.";

  const boost::container::flat_map<std::string, std::string> policyMaps = {
      {"AlwaysOn",
       "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
      {"AlwaysOff",
       "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
      {"LastState",
       "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};

  std::string powerRestorPolicy;

  auto policyMapsIt = policyMaps.find(policy);
  if (policyMapsIt == policyMaps.end()) {
    messages::propertyValueNotInList(aResp->res, policy, "PowerRestorePolicy");
    return;
  }

  powerRestorPolicy = policyMapsIt->second;

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      absl::AnyInvocable<void(const boost::system::error_code&)>(
          [aResp](const boost::system::error_code& ec) {
            if (ec) {
              messages::internalError(aResp->res);
              return;
            }
          }),
      "xyz.openbmc_project.Settings",
      "/xyz/openbmc_project/control/host0/power_restore_policy",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
      dbus::utility::DbusVariantType(powerRestorPolicy));
}

#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
/**
 * @brief Retrieves provisioning status
 *
 * @param[in] aResp     Shared pointer for completing asynchronous calls.
 *
 * @return None.
 */
inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp) {
  BMCWEB_LOG_DEBUG << "Get OEM information.";
  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
      "xyz.openbmc_project.PFR.Attributes", context,
      [aResp](const boost::system::error_code& ec,
              const dbus::utility::DBusPropertiesMap& propertiesList) {
        nlohmann::json& oemPFR =
            aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
        aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
            "#OemComputerSystem.OpenBmc";
        oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";

        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
          // not an error, don't have to have the interface
          oemPFR["ProvisioningStatus"] = "NotProvisioned";
          return;
        }

        const bool* provState = nullptr;
        const bool* lockState = nullptr;

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
            provState, "UfmLocked", lockState);

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

        if ((provState == nullptr) || (lockState == nullptr)) {
          BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
          messages::internalError(aResp->res);
          return;
        }

        if (*provState == true) {
          if (*lockState == true) {
            oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
          } else {
            oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
          }
        } else {
          oemPFR["ProvisioningStatus"] = "NotProvisioned";
        }
      });
}
#endif

/**
 * @brief Translate the PowerMode to a response message.
 *
 * @param[in] aResp  Shared pointer for generating response message.
 * @param[in] modeValue  PowerMode value to be translated
 *
 * @return None.
 */
inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                               const std::string& modeValue) {
  if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static") {
    aResp->res.jsonValue["PowerMode"] = "Static";
  } else if (modeValue ==
             "xyz.openbmc_project.Control.Power.Mode.PowerMode."
             "MaximumPerformance") {
    aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
  } else if (modeValue ==
             "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving") {
    aResp->res.jsonValue["PowerMode"] = "PowerSaving";
  } else if (modeValue ==
             "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM") {
    aResp->res.jsonValue["PowerMode"] = "OEM";
  } else {
    // Any other values would be invalid
    BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
    messages::internalError(aResp->res);
  }
}

/**
 * @brief Retrieves system power mode
 *
 * @param[in] aResp  Shared pointer for generating response message.
 *
 * @return None.
 */
inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  BMCWEB_LOG_DEBUG << "Get power mode.";

  // Get Power Mode object path:
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Control.Power.Mode"};
  managedStore::ManagedObjectStoreContext context(aResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/", 0, interfaces, context,
      [aResp, context](const boost::system::error_code& ec,
                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
                           << ec;
          // This is an optional D-Bus object so just return if
          // error occurs
          return;
        }
        if (subtree.empty()) {
          // As noted above, this is an optional interface so just return
          // if there is no instance found
          return;
        }
        if (subtree.size() > 1) {
          // More then one PowerMode object is not supported and is an
          // error
          BMCWEB_LOG_DEBUG
              << "Found more than 1 system D-Bus Power.Mode objects: "
              << subtree.size();
          messages::internalError(aResp->res);
          return;
        }
        if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) {
          BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
          messages::internalError(aResp->res);
          return;
        }
        const std::string& path = subtree[0].first;
        const std::string& service = subtree[0].second.begin()->first;
        if (service.empty()) {
          BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
          messages::internalError(aResp->res);
          return;
        }
        // Valid Power Mode object found, now read the current value
        dbus_utils::getProperty<std::string>(
            service, path, "xyz.openbmc_project.Control.Power.Mode",
            "PowerMode", context,
            [aResp](const boost::system::error_code& ec2,
                    const std::string& pmode) {
              if (ec2) {
                BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
                                 << ec2;
                messages::internalError(aResp->res);
                return;
              }

              aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
                  "Static", "MaximumPerformance", "PowerSaving"};

              BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
              translatePowerMode(aResp, pmode);
            });
      });
}

/**
 * @brief Validate the specified mode is valid and return the PowerMode
 * name associated with that string
 *
 * @param[in] aResp   Shared pointer for generating response message.
 * @param[in] modeString  String representing the desired PowerMode
 *
 * @return PowerMode value or empty string if mode is not valid
 */
inline std::string validatePowerMode(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& modeString) {
  std::string mode;

  if (modeString == "Static") {
    mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
  } else if (modeString == "MaximumPerformance") {
    mode =
        "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
  } else if (modeString == "PowerSaving") {
    mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
  } else {
    messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
  }
  return mode;
}

/**
 * @brief Sets system power mode.
 *
 * @param[in] aResp   Shared pointer for generating response message.
 * @param[in] pmode   System power mode from request.
 *
 * @return None.
 */
inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                         const std::string& pmode) {
  BMCWEB_LOG_DEBUG << "Set power mode.";

  std::string powerMode = validatePowerMode(aResp, pmode);
  if (powerMode.empty()) {
    return;
  }

  // Get Power Mode object path:
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Control.Power.Mode"};
  managedStore::ManagedObjectStoreContext requestContext(aResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/", 0, interfaces, requestContext,
      [aResp, powerMode](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
                           << ec;
          // This is an optional D-Bus object, but user attempted to patch
          messages::internalError(aResp->res);
          return;
        }
        if (subtree.empty()) {
          // This is an optional D-Bus object, but user attempted to patch
          messages::resourceNotFound(aResp->res, "ComputerSystem", "PowerMode");
          return;
        }
        if (subtree.size() > 1) {
          // More then one PowerMode object is not supported and is an
          // error
          BMCWEB_LOG_DEBUG
              << "Found more than 1 system D-Bus Power.Mode objects: "
              << subtree.size();
          messages::internalError(aResp->res);
          return;
        }
        if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) {
          BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
          messages::internalError(aResp->res);
          return;
        }
        const std::string& path = subtree[0].first;
        const std::string& service = subtree[0].second.begin()->first;
        if (service.empty()) {
          BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
          messages::internalError(aResp->res);
          return;
        }

        BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
                         << path;

        // Set the Power Mode property
        managedStore::GetManagedObjectStore()
            ->PostDbusCallToIoContextThreadSafe(
                aResp->strand_,
                absl::AnyInvocable<void(const boost::system::error_code&)>(
                    [aResp](const boost::system::error_code& ec2) {
                      if (ec2) {
                        messages::internalError(aResp->res);
                        return;
                      }
                    }),
                service, path, "org.freedesktop.DBus.Properties", "Set",
                "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
                dbus::utility::DbusVariantType(powerMode));
      });
}

/**
 * @brief Translates watchdog timeout action DBUS property value to redfish.
 *
 * @param[in] dbusAction    The watchdog timeout action in D-BUS.
 *
 * @return Returns as a string, the timeout action in Redfish terms. If
 * translation cannot be done, returns an empty string.
 */
inline std::string dbusToRfWatchdogAction(const std::string& dbusAction) {
  if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None") {
    return "None";
  }
  if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset") {
    return "ResetSystem";
  }
  if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff") {
    return "PowerDown";
  }
  if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle") {
    return "PowerCycle";
  }

  return "";
}

/**
 *@brief Translates timeout action from Redfish to DBUS property value.
 *
 *@param[in] rfAction The timeout action in Redfish.
 *
 *@return Returns as a string, the time_out action as expected by DBUS.
 *If translation cannot be done, returns an empty string.
 */

inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction) {
  if (rfAction == "None") {
    return "xyz.openbmc_project.State.Watchdog.Action.None";
  }
  if (rfAction == "PowerCycle") {
    return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
  }
  if (rfAction == "PowerDown") {
    return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
  }
  if (rfAction == "ResetSystem") {
    return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
  }

  return "";
}

/**
 * @brief Retrieves host watchdog timer properties over DBUS
 *
 * @param[in] aResp     Shared pointer for completing asynchronous calls.
 *
 * @return None.
 */
inline void getHostWatchdogTimer(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  BMCWEB_LOG_DEBUG << "Get host watchodg";
  managedStore::ManagedObjectStoreContext context(aResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
      "xyz.openbmc_project.State.Watchdog", context,
      [aResp](const boost::system::error_code& ec,
              const dbus::utility::DBusPropertiesMap& properties) {
        if (ec) {
          // watchdog service is stopped
          BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
          return;
        }

        BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";

        nlohmann::json& hostWatchdogTimer =
            aResp->res.jsonValue["HostWatchdogTimer"];

        // watchdog service is running/enabled
        hostWatchdogTimer["Status"]["State"] = "Enabled";

        const bool* enabled = nullptr;
        const std::string* expireAction = nullptr;

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
            "ExpireAction", expireAction);

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

        if (enabled != nullptr) {
          hostWatchdogTimer["FunctionEnabled"] = *enabled;
        }

        if (expireAction != nullptr) {
          std::string action = dbusToRfWatchdogAction(*expireAction);
          if (action.empty()) {
            messages::internalError(aResp->res);
            return;
          }
          hostWatchdogTimer["TimeoutAction"] = action;
        }
      });
}

/**
 * @brief Sets Host WatchDog Timer properties.
 *
 * @param[in] aResp      Shared pointer for generating response message.
 * @param[in] wdtEnable  The WDTimer Enable value (true/false) from incoming
 *                       RF request.
 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
 *
 * @return None.
 */
inline void setWDTProperties(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::optional<bool> wdtEnable,
    const std::optional<std::string>& wdtTimeOutAction) {
  BMCWEB_LOG_DEBUG << "Set host watchdog";

  if (wdtTimeOutAction) {
    std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
    // check if TimeOut Action is Valid
    if (wdtTimeOutActStr.empty()) {
      BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
                       << *wdtTimeOutAction;
      messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
                                       "TimeoutAction");
      return;
    }

    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        aResp->strand_,
        absl::AnyInvocable<void(const boost::system::error_code&)>(
            [aResp](const boost::system::error_code& ec) {
              if (ec) {
                BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
                messages::internalError(aResp->res);
                return;
              }
            }),
        "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
        "org.freedesktop.DBus.Properties", "Set",
        "xyz.openbmc_project.State.Watchdog", "ExpireAction",
        dbus::utility::DbusVariantType(wdtTimeOutActStr));
  }

  if (wdtEnable) {
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        aResp->strand_,
        absl::AnyInvocable<void(const boost::system::error_code&)>(
            [aResp](const boost::system::error_code& ec) {
              if (ec) {
                BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
                messages::internalError(aResp->res);
                return;
              }
            }),
        "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
        "org.freedesktop.DBus.Properties", "Set",
        "xyz.openbmc_project.State.Watchdog", "Enabled",
        dbus::utility::DbusVariantType(*wdtEnable));
  }
}

/**
 * @brief Parse the Idle Power Saver properties into json
 *
 * @param[in] aResp     Shared pointer for completing asynchronous calls.
 * @param[in] properties  IPS property data from DBus.
 *
 * @return true if successful
 */
inline bool parseIpsProperties(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const dbus::utility::DBusPropertiesMap& properties) {
  const bool* enabled = nullptr;
  const uint8_t* enterUtilizationPercent = nullptr;
  const uint64_t* enterDwellTime = nullptr;
  const uint8_t* exitUtilizationPercent = nullptr;
  const uint64_t* exitDwellTime = nullptr;

  const bool success = sdbusplus::unpackPropertiesNoThrow(
      dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
      "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
      enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
      "ExitDwellTime", exitDwellTime);

  if (!success) {
    return false;
  }

  if (enabled != nullptr) {
    aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
  }

  if (enterUtilizationPercent != nullptr) {
    aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
        *enterUtilizationPercent;
  }

  if (enterDwellTime != nullptr) {
    const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
    aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
        std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms).count();
  }

  if (exitUtilizationPercent != nullptr) {
    aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
        *exitUtilizationPercent;
  }

  if (exitDwellTime != nullptr) {
    const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
    aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
        std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms).count();
  }

  return true;
}

/**
 * @brief Retrieves host watchdog timer properties over DBUS
 *
 * @param[in] aResp     Shared pointer for completing asynchronous calls.
 *
 * @return None.
 */
inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  BMCWEB_LOG_DEBUG << "Get idle power saver parameters";

  // Get IdlePowerSaver object path:
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
  managedStore::ManagedObjectStoreContext context(aResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/", 0, interfaces, context,
      [aResp, context](const boost::system::error_code& ec,
                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_DEBUG
              << "DBUS response error on Power.IdlePowerSaver GetSubTree "
              << ec;
          messages::internalError(aResp->res);
          return;
        }
        if (subtree.empty()) {
          // This is an optional interface so just return
          // if there is no instance found
          BMCWEB_LOG_DEBUG << "No instances found";
          return;
        }
        if (subtree.size() > 1) {
          // More then one PowerIdlePowerSaver object is not supported and
          // is an error
          BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
                              "Power.IdlePowerSaver objects: "
                           << subtree.size();
          messages::internalError(aResp->res);
          return;
        }
        if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) {
          BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
          messages::internalError(aResp->res);
          return;
        }
        const std::string& path = subtree[0].first;
        const std::string& service = subtree[0].second.begin()->first;
        if (service.empty()) {
          BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
          messages::internalError(aResp->res);
          return;
        }

        // Valid IdlePowerSaver object found, now read the current values
        managedStore::GetManagedObjectStore()->getAllProperties(
            service, path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
            context,
            [aResp](const boost::system::error_code& ec2,
                    const dbus::utility::DBusPropertiesMap& properties) {
              if (ec2) {
                BMCWEB_LOG_ERROR
                    << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
                messages::internalError(aResp->res);
                return;
              }

              if (!parseIpsProperties(aResp, properties)) {
                messages::internalError(aResp->res);
                return;
              }
            });
      });

  BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
}

/**
 * @brief Retrieve the systemName suffix
 *
 * @param[in] systemName     String of systemName, assume it's "systemX"
 *
 * @return string of the suffix, empty string if it's invalid or empty
 */
inline std::string getSystemSuffix(const std::string& systemName) {
  constexpr std::string_view systemPrefix = "system";

  if (systemName.rfind(systemPrefix, 0) != 0) {
    // The systemName did not start with the prefix - return empty
    return "";
  }
  // Extract the part after "system" - empty string if there is no suffix
  return systemName.substr(systemPrefix.size());
}

/**
 * @brief Retrieves BM readiness signal from the file system
 *
 * @param[in] aResp     Shared pointer for completing asynchronous calls.
 * @param[in] systemName     String of systemName
 *
 * @return None.
 */
inline void getBMReady(const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  BMCWEB_LOG_DEBUG << "Get BMReady signal";
  nlohmann::json& googleBM =
      aResp->res.jsonValue["Oem"]["Google"]["BareMetalStatus"];

  googleBM["BareMetal"] = "Disabled";
  if (std::filesystem::exists(BM_SIGNAL_PATH)) {
    BMCWEB_LOG_DEBUG << "BMReady flag found";
    googleBM["BareMetal"] = "BareMetalReady";
  }
  BMCWEB_LOG_DEBUG << "EXIT: Get BMReady signal";
}

/**
 * @brief Retrieves NERF status from the file system
 *
 * @param[in] aResp     Shared pointer for completing asynchronous calls.
 * @param[in] systemName     String of systemName
 *
 * @return None.
 */
inline void getNERFStatus(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                          const std::string& systemName) {
  BMCWEB_LOG_DEBUG << "Get NERF status signal";

  nlohmann::json& googleNERF =
      aResp->res.jsonValue["Oem"]["Google"]["NERFStatus"];

  googleNERF["NERF"] = "NonBMMode";

  const std::string systemSuffix = getSystemSuffix(systemName);
  const std::string bmDriveCleaningFlagPath =
      "/run/bm-drive-cleaning.flag" + systemSuffix;
  const std::string bmDriveCleaningDoneAckFlagPath =
      "/run/bm-drive-cleaning-done-ack.flag" + systemSuffix;
  if (std::filesystem::exists(bmDriveCleaningDoneAckFlagPath)) {
    BMCWEB_LOG_DEBUG << "Cleaning was finished and acked by NERF";
    googleNERF["NERF"] = "UEFIboot";
  } else if (std::filesystem::exists(bmDriveCleaningFlagPath)) {
    BMCWEB_LOG_DEBUG << "Cleaning flag found, NERF must be in rendevouz";
    googleNERF["NERF"] = "SteadyState";
  }
  BMCWEB_LOG_DEBUG << "EXIT: Get NERF Status signal";
}

inline void getBootNumber(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                          const std::string& systemName,
                          const std::string& systemPath) {
  BMCWEB_LOG_INFO << "Get BootNumber property";
  aResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/" + systemName + "/Oem/Google/BootNumber";
  aResp->res.jsonValue["@odata.type"] =
      "#GoogleBootNumber.v1_0_0.GoogleBootNumber";

  std::string object;
  // Object Path for multi-host systems is
  // /xyz/openbmc_project/inventory/system/board/<platform>/<systemname>/chassis/motherboard/bios.
  // Whereas for single-host systems is /xyz/openbmc_project/inventory/<system
  // name>/chassis/motherboard/bios. In order to make sure that the correct path
  // is used we get it from dbus utilities.
  if (systemPath.empty()) {
    object = absl::StrCat("/xyz/openbmc_project/inventory/", systemName,
                          "/chassis/motherboard/bios");
  } else {
    object = absl::StrCat(systemPath, "/chassis/motherboard/bios");
  }

  managedStore::ManagedObjectStoreContext requestContext(aResp);
  dbus_utils::getProperty<uint32_t>(
      "xyz.openbmc_project.Smbios.MDR_V2", object,
      "xyz.openbmc_project.State.Host", "BootCount", requestContext,
      [aResp](const boost::system::error_code& ec, const uint32_t& number) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBUS BOOT COUNT response error: "
                           << ec.message();
          return;
        }

        aResp->res.jsonValue["BootNumber"] = number;
      });
}

/**
 * @brief Retrieves BM Instance properties from the file system
 *
 * @param[in] aResp     Shared pointer for completing asynchronous calls.
 * @param[in] systemName     String of systemName
 *
 * @return None.
 */
inline void getBMInstance(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                          const std::string& systemName) {
  BMCWEB_LOG_DEBUG << "Get BM Instance property";
  aResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/" + systemName + "/Oem/Google/BareMetalInstance";
  aResp->res.jsonValue["@odata.type"] =
      "#GoogleBareMetalInstance.v1_0_0.GoogleBareMetalInstance";

  const auto systemSuffix = getSystemSuffix(systemName);
  const std::array<std::pair<std::string_view, std::string>, 7>
      bmPropertyToPath = {
          {{"AssetTag", "/run/bm-instance/asset-tag" + systemSuffix},
           {"BoardSerialNumber",
            "/run/bm-instance/board-serial-number" + systemSuffix},
           {"Family", "/run/bm-instance/family" + systemSuffix},
           {"ProductName", "/run/bm-instance/product-name" + systemSuffix},
           {"SKU", "/run/bm-instance/sku" + systemSuffix},
           {"SystemSerialNumber",
            "/run/bm-instance/system-serial-number" + systemSuffix},
           {"UUID", "/run/bm-instance/uuid" + systemSuffix}}};

  for (const auto& [propertyName, filePath] : bmPropertyToPath) {
    // If the path doesn't exist, set it to an empty string
    if (!std::filesystem::exists(filePath)) {
      aResp->res.jsonValue[propertyName] = "";
      continue;
    }

    std::ifstream ifs;
    ifs.exceptions(std::ifstream::failbit);
    std::string property;
    try {
      ifs.open(filePath);
      std::getline(ifs, property);
    } catch (std::ios_base::failure& fail) {
      BMCWEB_LOG_DEBUG << "Faield to read - setting to default value: "
                       << filePath;
      aResp->res.jsonValue[propertyName] = "";
      continue;
    }
    aResp->res.jsonValue[propertyName] = property;
  }
  BMCWEB_LOG_DEBUG << "EXIT: Get BM Instance property";
}

/**
 * @brief Sets Idle Power Saver properties.
 *
 * @param[in] aResp      Shared pointer for generating response message.
 * @param[in] ipsEnable  The IPS Enable value (true/false) from incoming
 *                       RF request.
 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
 * before entering idle state.
 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
 * before exiting idle state
 *
 * @return None.
 */
inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                              const std::optional<bool> ipsEnable,
                              const std::optional<uint8_t> ipsEnterUtil,
                              const std::optional<uint64_t> ipsEnterTime,
                              const std::optional<uint8_t> ipsExitUtil,
                              const std::optional<uint64_t> ipsExitTime) {
  BMCWEB_LOG_DEBUG << "Set idle power saver properties";

  // Get IdlePowerSaver object path:
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
  managedStore::ManagedObjectStoreContext requestContext(aResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/", 0, interfaces, requestContext,
      [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil, ipsExitTime](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_DEBUG
              << "DBUS response error on Power.IdlePowerSaver GetSubTree "
              << ec;
          messages::internalError(aResp->res);
          return;
        }
        if (subtree.empty()) {
          // This is an optional D-Bus object, but user attempted to patch
          messages::resourceNotFound(aResp->res, "ComputerSystem",
                                     "IdlePowerSaver");
          return;
        }
        if (subtree.size() > 1) {
          // More then one PowerIdlePowerSaver object is not supported and
          // is an error
          BMCWEB_LOG_DEBUG
              << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
              << subtree.size();
          messages::internalError(aResp->res);
          return;
        }
        if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1)) {
          BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
          messages::internalError(aResp->res);
          return;
        }
        const std::string& path = subtree[0].first;
        const std::string& service = subtree[0].second.begin()->first;
        if (service.empty()) {
          BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
          messages::internalError(aResp->res);
          return;
        }

        // Valid Power IdlePowerSaver object found, now set any values that
        // need to be updated

        if (ipsEnable) {
          managedStore::GetManagedObjectStore()
              ->PostDbusCallToIoContextThreadSafe(
                  aResp->strand_,
                  absl::AnyInvocable<void(const boost::system::error_code&)>(
                      [aResp](const boost::system::error_code& ec2) {
                        if (ec2) {
                          BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
                          messages::internalError(aResp->res);
                          return;
                        }
                      }),
                  service, path, "org.freedesktop.DBus.Properties", "Set",
                  "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
                  dbus::utility::DbusVariantType(*ipsEnable));
        }
        if (ipsEnterUtil) {
          managedStore::GetManagedObjectStore()
              ->PostDbusCallToIoContextThreadSafe(
                  aResp->strand_,
                  absl::AnyInvocable<void(const boost::system::error_code&)>(
                      [aResp](const boost::system::error_code& ec2) {
                        if (ec2) {
                          BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
                          messages::internalError(aResp->res);
                          return;
                        }
                      }),
                  service, path, "org.freedesktop.DBus.Properties", "Set",
                  "xyz.openbmc_project.Control.Power.IdlePowerSaver",
                  "EnterUtilizationPercent",
                  dbus::utility::DbusVariantType(*ipsEnterUtil));
        }
        if (ipsEnterTime) {
          // Convert from seconds into milliseconds for DBus
          const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
          managedStore::GetManagedObjectStore()
              ->PostDbusCallToIoContextThreadSafe(
                  aResp->strand_,
                  absl::AnyInvocable<void(const boost::system::error_code&)>(
                      [aResp](const boost::system::error_code& ec2) {
                        if (ec2) {
                          BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
                          messages::internalError(aResp->res);
                          return;
                        }
                      }),
                  service, path, "org.freedesktop.DBus.Properties", "Set",
                  "xyz.openbmc_project.Control.Power.IdlePowerSaver",
                  "EnterDwellTime",
                  dbus::utility::DbusVariantType(timeMilliseconds));
        }
        if (ipsExitUtil) {
          managedStore::GetManagedObjectStore()
              ->PostDbusCallToIoContextThreadSafe(
                  aResp->strand_,
                  absl::AnyInvocable<void(const boost::system::error_code&)>(
                      [aResp](const boost::system::error_code& ec2) {
                        if (ec2) {
                          BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
                          messages::internalError(aResp->res);
                          return;
                        }
                      }),
                  service, path, "org.freedesktop.DBus.Properties", "Set",
                  "xyz.openbmc_project.Control.Power.IdlePowerSaver",
                  "ExitUtilizationPercent",
                  dbus::utility::DbusVariantType(*ipsExitUtil));
        }
        if (ipsExitTime) {
          // Convert from seconds into milliseconds for DBus
          const uint64_t timeMilliseconds = *ipsExitTime * 1000;
          managedStore::GetManagedObjectStore()
              ->PostDbusCallToIoContextThreadSafe(
                  aResp->strand_,
                  absl::AnyInvocable<void(const boost::system::error_code&)>(
                      [aResp](const boost::system::error_code& ec2) {
                        if (ec2) {
                          BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
                          messages::internalError(aResp->res);
                          return;
                        }
                      }),
                  service, path, "org.freedesktop.DBus.Properties", "Set",
                  "xyz.openbmc_project.Control.Power.IdlePowerSaver",
                  "ExitDwellTime",
                  dbus::utility::DbusVariantType(timeMilliseconds));
        }
      });

  BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
}

/**
 * @brief Sets BMInstnace  properties.
 *
 * @param[in] aResp             Shared pointer for generating response message.
 * @param[in] systemName        String of systemName
 * @param[in] bmiAssetTag       BM instance asset tag to be set
 * @param[in] bmiBoardSerialNumber   BM instance board serial number to be set
 * @param[in] bmiFamily         BM instance family to be set
 * @param[in] bmiProductName    BM instance product name to be set
 * @param[in] bmiSKU            BM instance SKU to be set
 * @param[in] bmiSystemSerialNumber   BM instance syste serial number to be set
 * @param[in] bmiUUID           BM instance UUID to be set
 *
 * @return None.
 */
inline void setBMInstance(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& systemName, const std::string& bmiAssetTag,
    const std::string& bmiBoardSerialNumber, const std::string& bmiFamily,
    const std::string& bmiProductName, const std::string& bmiSKU,
    const std::string& bmiSystemSerialNumber, const std::string& bmiUUID) {
  BMCWEB_LOG_DEBUG << "Set BM Instance properties";

  std::filesystem::path bmInstanceDirPath = "/run/bm-instance";

  // Create parent directories if they don't exist
  std::error_code ec;
  if (!std::filesystem::exists(bmInstanceDirPath, ec)) {
    std::filesystem::create_directories(bmInstanceDirPath, ec);
  }
  if (ec) {
    if (!std::filesystem::exists(bmInstanceDirPath, ec)) {
      BMCWEB_LOG_DEBUG << "Failed to create base directory("
                       << bmInstanceDirPath << "): " << ec;
      messages::internalError(aResp->res);
      return;
    }
  }

  const std::string systemSuffix = getSystemSuffix(systemName);
  // Helper function to output the value to the file path
  auto processFile = [&systemSuffix](const std::filesystem::path& path,
                                     std::string_view val) -> bool {
    std::filesystem::path appendedPath = path;
    appendedPath.concat(systemSuffix);
    std::ofstream file(appendedPath);
    if (!file) {
      BMCWEB_LOG_DEBUG << "Failed to create: " << appendedPath.string();
      return false;
    }
    file << val << '\n';
    file.close();
    return true;
  };

  if (!bmiAssetTag.empty()) {
    if (!processFile(bmInstanceDirPath / "asset-tag", bmiAssetTag)) {
      messages::internalError(aResp->res);
      return;
    }
  }
  if (!bmiBoardSerialNumber.empty()) {
    if (!processFile(bmInstanceDirPath / "board-serial-number",
                     bmiBoardSerialNumber)) {
      messages::internalError(aResp->res);
      return;
    }
  }
  if (!bmiFamily.empty()) {
    if (!processFile(bmInstanceDirPath / "family", bmiFamily)) {
      messages::internalError(aResp->res);
      return;
    }
  }
  if (!bmiProductName.empty()) {
    if (!processFile(bmInstanceDirPath / "product-name", bmiProductName)) {
      messages::internalError(aResp->res);
      return;
    }
  }
  if (!bmiSKU.empty()) {
    if (!processFile(bmInstanceDirPath / "sku", bmiSKU)) {
      messages::internalError(aResp->res);
      return;
    }
  }
  if (!bmiSystemSerialNumber.empty()) {
    if (!processFile(bmInstanceDirPath / "system-serial-number",
                     bmiSystemSerialNumber)) {
      messages::internalError(aResp->res);
      return;
    }
  }
  if (!bmiUUID.empty()) {
    if (!processFile(bmInstanceDirPath / "uuid", bmiUUID)) {
      messages::internalError(aResp->res);
      return;
    }
  }

  messages::success(aResp->res);
  BMCWEB_LOG_DEBUG << "EXIT: Set BM Instance properties";
}

inline void handleComputerSystemHead(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  asyncResp->res.addHeader(boost::beast::http::field::link,
                           "</redfish/v1/JsonSchemas/ComputerSystemCollection/"
                           "ComputerSystemCollection.json>; rel=describedby");
}

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

  asyncResp->res.addHeader(boost::beast::http::field::link,
                           "</redfish/v1/JsonSchemas/"
                           "ComputerSystemCollection.json>; rel=describedby");
  asyncResp->res.jsonValue["@odata.type"] =
      "#ComputerSystemCollection.ComputerSystemCollection";
  asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
  asyncResp->res.jsonValue["Name"] = "Computer System Collection";

  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/", 0, systemInterfaces, context,
      [asyncResp, context](const boost::system::error_code& ec,
                           const std::vector<std::string>& objects) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error";
          messages::internalError(asyncResp->res);
          return;
        }
        if (system_utils::isHardcodedSingleHost(objects.size())) {
          nlohmann::json::object_t system;
          system["@odata.id"] = "/redfish/v1/Systems/system";
          asyncResp->res.jsonValue["Members"].emplace_back(system);
          asyncResp->res.jsonValue["Members@odata.count"] =
              asyncResp->res.jsonValue["Members"].size();
          return;
        }
        // Otherwise list all systems
        for (const auto& object : objects) {
          std::string systemName = object.substr(object.rfind('/'));
          nlohmann::json::object_t system;
          system["@odata.id"] = "/redfish/v1/Systems" + systemName;
          asyncResp->res.jsonValue["Members"].emplace_back(system);
        }
        asyncResp->res.jsonValue["Members@odata.count"] =
            asyncResp->res.jsonValue["Members"].size();
      });
}

/**
 * SystemsCollection derived class for delivering ComputerSystems Collection
 * Schema
 */
inline void requestRoutesSystemsCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
      .privileges(redfish::privileges::headComputerSystemCollection)
      .methods(boost::beast::http::verb::head)(
          std::bind_front(handleComputerSystemHead, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
      .privileges(redfish::privileges::getComputerSystemCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetSystemsCollection, std::ref(app)));
}

/**
 * Function transceives data with dbus directly.
 */
inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
  constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
  constexpr char const* interfaceName = "xyz.openbmc_project.Control.Host.NMI";
  constexpr char const* method = "NMI";

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      absl::AnyInvocable<void(const boost::system::error_code&)>(
          [asyncResp](const boost::system::error_code& ec) {
            if (ec) {
              BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
              messages::internalError(asyncResp->res);
              return;
            }
            messages::success(asyncResp->res);
          }),
      serviceName, objectPath, interfaceName, method);
}

inline void sendPowerSystemCommand(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& command, const std::string& resetType,
    const std::string& service, const std::string& path,
    const std::string& interface, const std::string& property) {
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      absl::AnyInvocable<void(const boost::system::error_code&)>(
          [asyncResp, resetType](const boost::system::error_code ec) {
            if (ec) {
              BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
              if (ec.value() == boost::asio::error::invalid_argument) {
                messages::actionParameterNotSupported(asyncResp->res, resetType,
                                                      "Reset");
              } else {
                messages::internalError(asyncResp->res);
              }
              return;
            }
            messages::success(asyncResp->res);
          }),
      service, path, "org.freedesktop.DBus.Properties", "Set", interface,
      property, dbus::utility::DbusVariantType{command});
}

struct SystemResetCommand {
  std::string command = "";  // NOLINT
  bool hostCommand = true;
  bool validCommand = true;
};

inline SystemResetCommand GetSystemResetCommandFromInput(
    const std::string& resetType) {
  if ((resetType == "On") || (resetType == "ForceOn")) {
    return SystemResetCommand{
        .command = "xyz.openbmc_project.State.Host.Transition.On",
        .hostCommand = true};
  }
  if (resetType == "ForceOff") {
    return SystemResetCommand{
        .command = "xyz.openbmc_project.State.Chassis.Transition.Off",
        .hostCommand = false};
  }
  if (resetType == "ForceRestart") {
    return SystemResetCommand{
        .command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot",
        .hostCommand = true};
  }
  if (resetType == "GracefulShutdown") {
    return SystemResetCommand{
        .command = "xyz.openbmc_project.State.Host.Transition.Off",
        .hostCommand = true};
  }
  if (resetType == "GracefulRestart") {
    return SystemResetCommand{
        .command =
            "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot",
        .hostCommand = true};
  }
  if (resetType == "PowerCycle") {
    return SystemResetCommand{
        .command = "xyz.openbmc_project.State.Host.Transition.Reboot",
        .hostCommand = true};
  }
  // TODO(b/294130541) (b/335339881)
  //  On the gsz platform (GracefulShutdown) does forced shutdown in
  //  x86-power-control This second call path was needed for the bm use case
  //  This is ONLY supported on "gsz"
#ifdef BMCWEB_ENABLE_REALLY_GRACEFUL_SHUTDOWN
  if (resetType == "ReallyGracefulShutDownTechDebt") {
    return SystemResetCommand{
        .command =
            "xyz.openbmc_project.State.Host.Transition.ReallyGracefulShutDown",
        .hostCommand = true};
  }
#endif  // BMCWEB_ENABLE_REALLY_GRACEFUL_SHUTDOWN
  return SystemResetCommand{.validCommand = false};
}

/* Have systemd run a curl command in a set amount of time
 *  resetURI: Chassis or Systems based on where you want to reset
 *  resetTimeSec: The amount of seconds to delay reset
 *  resetOp: same as resetType variable here
 *  asyncResp update the response
 */

void delayResetSystem(std::string_view systemName, int delayTimeSecs,
                      std::string_view resetType,
                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp);

/*
 * Handles System reset by creating the DBus call associated with the requested
 * reset.
 *
 * systemPath is object path of the related Item.System object to call the
 * ComputerSystem.Reset call on. This is needed to find its associated power
 * control objects.
 *
 * If systemPath is /xyz/openbmc_project/state/host1 (sample Item.System object)
 * Then host power state objects are associated with forward association
 * system_power and chassis power state objects are associated with forward
 * asociation chassis_power
 */
inline void sendSystemResetAction(
    const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemPath, const std::string& systemName) {
  std::string resetType;
  std::optional<int> delayTimeSec;
  if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType,
                                 "Delay", delayTimeSec)) {
    return;
  }

  if (resetType == "Nmi") {
    doNMI(asyncResp);
    return;
  }

  SystemResetCommand systemResetCommand =
      GetSystemResetCommandFromInput(resetType);

  if (!systemResetCommand.validCommand) {
    messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
    return;
  }

  // Get the command and host vs. chassis
  std::string command = systemResetCommand.command;
  bool hostCommand = systemResetCommand.hostCommand;
  if (delayTimeSec.has_value() && delayTimeSec.value() > 900)  // 15 minutes
  {
    BMCWEB_LOG_DEBUG << "reset delay timer too large, >900";
    messages::propertyValueOutOfRange(asyncResp->res, "900", "Delay");
    return;
  }
  if (delayTimeSec.has_value() && delayTimeSec.value() <= 900 &&
      (resetType == "On" || resetType == "ForceOn" || resetType == "ForceOff" ||
       resetType == "ForceRestart" || resetType == "GracefulShutdown" ||
       resetType == "PowerCycle")) {
    BMCWEB_LOG_DEBUG << "Seting delayed " << resetType;
    delayResetSystem(systemName, delayTimeSec.value(), resetType, asyncResp);
    return;
  }
  if (hostCommand) {
    // For single system servers, the power state object is hardcoded
    if (systemPath.empty()) {
      sendPowerSystemCommand(
          asyncResp, command, resetType, "xyz.openbmc_project.State.Host",
          "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
          "RequestedHostTransition");
      return;
    }

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getAssociatedSubTree(
        sdbusplus::message::object_path(systemPath + "/host_power"),
        sdbusplus::message::object_path("/xyz/openbmc_project/state"), 0,
        std::array<std::string_view, 1>{"xyz.openbmc_project.State.Host"},
        requestContext,
        [asyncResp, command, resetType](
            const boost::system::error_code ec,
            const dbus::utility::MapperGetSubTreeResponse& objects) {
          if (ec || objects.empty()) {
            BMCWEB_LOG_ERROR
                << "Host power control not associated with system object";
            messages::internalError(asyncResp->res);
            return;
          }

          // There should only be one host power control object associated
          // with this system
          if (objects.size() > 1) {
            BMCWEB_LOG_ERROR << "Too many host power control objects "
                                "associated with the system";
            messages::internalError(asyncResp->res);
            return;
          }

          // Map1: [key, val] -> [objectPath, Map2]
          // Map2: [key, val] -> [serviceName, list of interfaces]
          const std::string powerControlPath = objects[0].first;

          // This object path can have multiple services, we need the one that
          // contains "State.Host"
          for (const auto& serviceMapping : objects[0].second) {
            // Host 1 object is implemented by
            // xyz.openbmc_project.State.Host1 Cannot directly find
            // interface as the different host's have different services
            if (absl::StrContains(serviceMapping.first,
                                  "xyz.openbmc_project.State.Host")) {
              sendPowerSystemCommand(asyncResp, command, resetType,
                                     serviceMapping.first, powerControlPath,
                                     "xyz.openbmc_project.State.Host",
                                     "RequestedHostTransition");
              return;
            }
          }

          BMCWEB_LOG_ERROR
              << "Could not find correct host Power Control Object";
          messages::internalError(asyncResp->res);
          return;
        });
  } else {
    // For single system servers, the power state object is hardcoded
    if (systemPath.empty()) {
      sendPowerSystemCommand(
          asyncResp, command, resetType, "xyz.openbmc_project.State.Chassis",
          "/xyz/openbmc_project/state/chassis0",
          "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition");
      return;
    }

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getAssociatedSubTree(
        sdbusplus::message::object_path(systemPath + "/chassis_power"),
        sdbusplus::message::object_path("/xyz/openbmc_project/state"), 0,
        std::array<std::string_view, 1>{"xyz.openbmc_project.State.Chassis"},
        requestContext,
        [asyncResp, command, resetType](
            const boost::system::error_code ec,
            const dbus::utility::MapperGetSubTreeResponse& objects) {
          if (ec || objects.empty()) {
            BMCWEB_LOG_ERROR
                << "Chassis power control not associated with system object";
            messages::internalError(asyncResp->res);
            return;
          }

          // There should only be one chassis power control object associated
          // with this system
          if (objects.size() > 1) {
            BMCWEB_LOG_ERROR << "Too many chassis power control objects "
                                "associated with the system";
            messages::internalError(asyncResp->res);
            return;
          }

          // Map1: [key, val] -> [objectPath, Map2]
          // Map2: [key, val] -> [serviceName, list of interfaces]
          const std::string powerControlPath = objects[0].first;

          // This object path can have multiple services, we need the one that
          // contains "State.Host"
          for (const auto& serviceMapping : objects[0].second) {
            if (absl::StrContains(serviceMapping.first,
                                  "xyz.openbmc_project.State.Chassis")) {
              sendPowerSystemCommand(asyncResp, command, resetType,
                                     serviceMapping.first, powerControlPath,
                                     "xyz.openbmc_project.State.Chassis",
                                     "RequestedPowerTransition");
              return;
            }
          }

          BMCWEB_LOG_ERROR
              << "Could not find correct chassis Power Control Object";
          messages::internalError(asyncResp->res);
          return;
        });
  }
}

inline void handlePostComputerSystemReset(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/", 0, systemInterfaces, requestContext,
      [req, asyncResp, systemName](const boost::system::error_code& ec,
                                   const std::vector<std::string>& objects) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error";
          messages::internalError(asyncResp->res);
          return;
        }
        system_utils::findSystemPathAndTriggerCallback(
            asyncResp, systemName, objects,
            [req, systemName](const std::shared_ptr<bmcweb::AsyncResp>& resp,
                              const std::string& objectPath) {
              sendSystemResetAction(req, resp, objectPath, systemName);
            });
      });
}

/**
 * SystemActionsReset class supports handle POST method for Reset action.
 * The class retrieves and sends data directly to D-Bus.
 */
inline void requestRoutesSystemActionsReset(App& app) {
  /**
   * Function handles POST method request.
   * Analyzes POST body message before sends Reset request data to D-Bus.
   */
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
      .privileges(redfish::privileges::postComputerSystem)
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handlePostComputerSystemReset, std::ref(app)));
  ;
}

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

  const std::string systemSuffix = getSystemSuffix(systemName);
  const std::string bmDriveCleaningDoneFlagPath =
      "/run/bm-drive-cleaning-done.flag" + systemSuffix;
  const std::string bmDriveCleaningDoneAckFlagPath =
      "/run/bm-drive-cleaning-done-ack.flag" + systemSuffix;

  std::error_code ec;
  if (std::filesystem::exists(bmDriveCleaningDoneFlagPath, ec) ||
      std::filesystem::exists(bmDriveCleaningDoneAckFlagPath, ec)) {
    BMCWEB_LOG_DEBUG
        << "NERF was successfully notified to go into UEFI boot already";
    messages::success(asyncResp->res);
    return;
  }
  if (!std::filesystem::exists(bmDriveCleaningDoneFlagPath, ec)) {
    std::ofstream ofs;
    ofs.open(bmDriveCleaningDoneFlagPath, std::ofstream::out);
    ofs.close();

    BMCWEB_LOG_DEBUG << "Successfully created flag file: "
                     << bmDriveCleaningDoneFlagPath;

    messages::success(asyncResp->res);
    return;
  }
}

/**
 * Notify BMC to let NERF boot to Guest OS
 */
inline void requestRoutesSystemBootGuestOS(App& app) {
  /**
   * Function handles POST method request.
   */
  BMCWEB_ROUTE(
      app,
      "/redfish/v1/Systems/<str>/Actions/Oem/GoogleComputerSystem.BootGuestOS/")
      .privileges(redfish::privileges::postComputerSystem)
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handlePostSystemBootGuestOS, std::ref(app)));
}

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

  asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/System/" + systemName + "/Oem/Google/BootGuestOSActionInfo";
  asyncResp->res.jsonValue["Name"] = "Boot Guest OS";
  asyncResp->res.jsonValue["Id"] = "BootGuestOS";
}

/**
 * Action Info for notifying BMC to let NERF boot to Guest OS
 */
inline void requestRoutesSystemBootGuestOSInfo(App& app) {
  /**
   * Function handles POST method request.
   */
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Oem/Google/BootGuestOSActionInfo/")
      .privileges(redfish::privileges::getActionInfo)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetSystemBootGuestOSInfo, std::ref(app)));
}

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

  asyncResp->res.addHeader(boost::beast::http::field::link,
                           "</redfish/v1/JsonSchemas/ComputerSystem/"
                           "ComputerSystem.json>; rel=describedby");
}

inline void afterPortRequest(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const boost::system::error_code& ec,
    const std::vector<std::tuple<std::string, std::string, bool>>& socketData) {
  if (ec) {
    messages::internalError(asyncResp->res);
    return;
  }
  for (const auto& data : socketData) {
    const std::string& socketPath = get<0>(data);
    const std::string& protocolName = get<1>(data);
    bool isProtocolEnabled = get<2>(data);
    nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
    dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
    // need to retrieve port number for
    // obmc-console-ssh service
    if (protocolName == "SSH") {
      managedStore::ManagedObjectStoreContext requestContext(asyncResp);
      getPortNumber(socketPath, requestContext,
                    [asyncResp, protocolName](
                        const boost::system::error_code ec1, int portNumber) {
                      if (ec1) {
                        messages::internalError(asyncResp->res);
                        return;
                      }
                      nlohmann::json& dataJson1 =
                          asyncResp->res.jsonValue["SerialConsole"];
                      dataJson1[protocolName]["Port"] = portNumber;
                    });
    }
  }
}

inline void handleComputerSystem(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemObjectPath, const std::string& systemName,
    bool multiHost) {
  // Handling both single-system and multi-system cases
  asyncResp->res.addHeader(boost::beast::http::field::link,
                           "</redfish/v1/JsonSchemas/ComputerSystem/"
                           "ComputerSystem.json>; rel=describedby");
  asyncResp->res.jsonValue["@odata.type"] =
      "#ComputerSystem.v1_16_0.ComputerSystem";
  asyncResp->res.jsonValue["Name"] = systemName;
  asyncResp->res.jsonValue["Id"] = systemName;
  asyncResp->res.jsonValue["SystemType"] = "Physical";
  asyncResp->res.jsonValue["Description"] = "Computer System";
  asyncResp->res.jsonValue["@odata.id"] =
      absl::StrCat("/redfish/v1/Systems/", systemName);
  asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
      absl::StrCat("/redfish/v1/Systems/", systemName,
                   "/Actions/ComputerSystem.Reset");
  asyncResp->res
      .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
      absl::StrCat("/redfish/v1/Systems/", systemName, "/ResetActionInfo");
  asyncResp->res.jsonValue["Processors"]["@odata.id"] =
      absl::StrCat("/redfish/v1/Systems/", systemName, "/Processors");
  asyncResp->res.jsonValue["Storage"]["@odata.id"] =
      absl::StrCat("/redfish/v1/Systems/", systemName, "/Storage");
  asyncResp->res.jsonValue["Bios"]["@odata.id"] =
      absl::StrCat("/redfish/v1/Systems/", systemName, "/Bios");
  getBMReady(asyncResp);
  if constexpr (enableGoogleBaremetal) {
    asyncResp->res.jsonValue["Actions"]["Oem"]["Google"]
                            ["#GoogleComputerSystem.BootGuestOS"]["target"] =
        absl::StrCat("/redfish/v1/Systems/", systemName,
                     "/Actions/Oem/GoogleComputerSystem.BootGuestOS");
    asyncResp->res
        .jsonValue["Actions"]["Oem"]["Google"]
                  ["#GoogleComputerSystem.BootGuestOS"]["@Redfish.ActionInfo"] =
        absl::StrCat("/redfish/v1/Systems/", systemName,
                     "/Oem/Google/BootGuestOSActionInfo");
    asyncResp->res
        .jsonValue["Oem"]["Google"]["BareMetalInstance"]["@odata.id"] =
        absl::StrCat("/redfish/v1/Systems/", systemName,
                     "/Oem/Google/BareMetalInstance");
    getNERFStatus(asyncResp, systemName);
  }

#ifdef ENABLE_REDFISH_CONFIGURE_IFS
  asyncResp->res
      .jsonValue["Actions"]["Oem"]["Google"]
                ["#GoogleComputerSystem.ResetCpuIfsPattern"]["target"] =
      absl::StrCat("/redfish/v1/Systems/", systemName,
                   "/Actions/Oem/GoogleComputerSystem.ResetCpuIfsPattern");
  if (std::shared_ptr<milotic_tlbmc::SystemRegistry> registry =
          managedStore::GetManagedObjectStore()->GetSystemRegistry()) {
    absl::StatusOr<std::string> pattern =
        registry->GetBase64EncodedIfsPattern(systemName);
    if (!pattern.ok()) {
      BMCWEB_LOG_ERROR << "Failed to get Base64 IFS pattern: "
                       << pattern.status();
      messages::internalError(asyncResp->res);
    } else {
      asyncResp->res.jsonValue["Oem"]["Google"]["CpuIfsPatternBase64"] =
          std::move(*pattern);
    }
  }
#endif

#ifdef BMCWEB_ENABLE_REDFISH_SYSTEM_BOOTNUMBER
  asyncResp->res.jsonValue["Oem"]["Google"]["BootNumber"]["@odata.id"] =
      absl::StrCat("/redfish/v1/Systems/", systemName,
                   "/Oem/Google/BootNumber");
#endif

  asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
      absl::StrCat("/redfish/v1/Systems/", systemName, "/LogServices");
  asyncResp->res.jsonValue["Memory"]["@odata.id"] =
      absl::StrCat("/redfish/v1/Systems/", systemName, "/Memory");
  asyncResp->res.jsonValue["Oem"]["Google"]["BootTime"]["@odata.id"] =
      absl::StrCat("/redfish/v1/Systems/", systemName, "/Oem/Google/BootTime");

  nlohmann::json::array_t managedBy;
  nlohmann::json& manager = managedBy.emplace_back();
  manager["@odata.id"] = "/redfish/v1/Managers/bmc";
  asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);

  getMainChassisId(
      asyncResp, [](const std::string& chassisId,
                    const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
        nlohmann::json::array_t chassisArray;
        nlohmann::json& chassis = chassisArray.emplace_back();
        chassis["@odata.id"] =
            crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId);
        aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
      });

  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  asyncResp->res.jsonValue["Status"]["State"] = "Enabled";

  managedStore::GetManagedObjectStore()->getAssociatedSubTree(
      sdbusplus::message::object_path(systemObjectPath + "/host_power"),
      sdbusplus::message::object_path("/xyz/openbmc_project/state"), 0,
      hostStateInterfaces, requestContext,
      [asyncResp, systemObjectPath, multiHost](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreeResponse& objects) {
        if (ec) {
          BMCWEB_LOG_ERROR
              << "Host power control not associated with system object";
          messages::internalError(asyncResp->res);
          return;
        }

        // There should only be one host power control object associated with
        // this system
        if (objects.size() > 1) {
          BMCWEB_LOG_ERROR << "Too many host power control objects associated "
                              "with the system";
          messages::internalError(asyncResp->res);
          return;
        }

        getHostState(asyncResp, systemObjectPath, objects);
        if (!multiHost) {
          getLastResetTime(asyncResp, systemObjectPath, objects);
        }
      });

  // Handling last reset time for multi-system
  if (multiHost) {
    managedStore::GetManagedObjectStore()->getAssociatedSubTree(
        sdbusplus::message::object_path(systemObjectPath + "/chassis_power"),
        sdbusplus::message::object_path("/xyz/openbmc_project/state"), 0,
        chassisStateInterfaces, requestContext,
        [asyncResp, systemObjectPath](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreeResponse& objects) {
          if (ec) {
            BMCWEB_LOG_ERROR
                << "Chassis power control not associated with system object";
            messages::internalError(asyncResp->res);
            return;
          }

          // There should only be one chassis power control object associated
          // with this system
          if (objects.size() > 1) {
            BMCWEB_LOG_ERROR << "Too many chassis power control objects "
                                "associated with the system";
            messages::internalError(asyncResp->res);
            return;
          }

          getLastResetTime(asyncResp, systemObjectPath, objects);
        });
  }

  getPCIeDeviceList(asyncResp, systemName, "PCIeDevices");

  getBootProperties(asyncResp, systemName, multiHost);

  // Handling multi-system and single-system separately. In the future, the
  // goal is to not have to separate these two. However, until code is
  // refactored, there will be diffs.

  // Handle single-system code
  if (!multiHost) {
    asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
    asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
        "Disabled";
    asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
        static_cast<uint64_t>(0);
    asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
    asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
        "/redfish/v1/Systems/system/FabricAdapters";

    asyncResp->res.jsonValue["Status"]["Health"] = "OK";

    // Fill in SerialConsole info
    asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
    asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;

    // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
    asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
    asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
    asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
        "Press ~. to exit console";
    getPortStatusAndPath(std::span{protocolToDBusForSystems}, requestContext,
                         std::bind_front(afterPortRequest, asyncResp));

    auto health = std::make_shared<HealthPopulate>(asyncResp);
#ifdef HEALTH_POPULATE
    constexpr std::array<std::string_view, 4> inventoryForSystems{
        "xyz.openbmc_project.Inventory.Item.Dimm",
        "xyz.openbmc_project.Inventory.Item.Cpu",
        "xyz.openbmc_project.Inventory.Item.Drive",
        "xyz.openbmc_project.Inventory.Item.StorageController"};

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTreePaths(
        "/", 0, inventoryForSystems, requestContext,
        [health](const boost::system::error_code& ec,
                 const std::vector<std::string>& resp) {
          if (ec) {
            // no inventory
            return;
          }

          health->inventory = resp;
        });
    health->populate();
#endif

    getLocationIndicatorActive(asyncResp);
    // TODO (Gunnar): Remove IndicatorLED after enough time has
    // passed
    getIndicatorLedState(asyncResp);
    getComputerSystem(asyncResp, health, systemName);
    getBootProgress(asyncResp);
    getBootProgressLastStateTime(asyncResp);
    getBootProgressOemLastState(asyncResp);
    getHostWatchdogTimer(asyncResp);
    getPowerRestorePolicy(asyncResp);
    getAutomaticRetry(asyncResp);
#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
    getProvisioningStatus(asyncResp);
#endif
    getTrustedModuleRequiredToBoot(asyncResp);
    getPowerMode(asyncResp);
    getIdlePowerSaver(asyncResp);
  }
}

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

  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/", 0, systemInterfaces, requestContext,
      [asyncResp, systemName](const boost::system::error_code& ec,
                              const std::vector<std::string>& objects) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error";
          messages::internalError(asyncResp->res);
          return;
        }

        system_utils::findSystemPathAndTriggerCallback(
            asyncResp, systemName, objects,
            [systemName](const std::shared_ptr<bmcweb::AsyncResp>& resp,
                         const std::string& objectPath) {
              const bool multiHost = !objectPath.empty();
              handleComputerSystem(resp, objectPath, systemName, multiHost);
            });
      });
}

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

  std::optional<bool> locationIndicatorActive;
  std::optional<std::string> indicatorLed;
  std::optional<std::string> assetTag;
  std::optional<std::string> powerRestorePolicy;
  std::optional<std::string> powerMode;
  std::optional<bool> wdtEnable;
  std::optional<std::string> wdtTimeOutAction;
  std::optional<std::string> bootSource;
  std::optional<std::string> bootType;
  std::optional<std::string> bootEnable;
  std::optional<std::vector<std::string>> bootOrder;
  std::optional<std::string> bootNext;
  std::optional<std::string> bootAutomaticRetry;
  std::optional<bool> bootTrustedModuleRequired;
  std::optional<bool> ipsEnable;
  std::optional<uint8_t> ipsEnterUtil;
  std::optional<uint64_t> ipsEnterTime;
  std::optional<uint8_t> ipsExitUtil;
  std::optional<uint64_t> ipsExitTime;
  std::optional<std::string> cpuIfsPatternBase64;
  // clang-format off
  if (!json_util::readJsonPatch(
          req, asyncResp->res,
          "IndicatorLED", indicatorLed,
          "LocationIndicatorActive", locationIndicatorActive,
          "AssetTag", assetTag,
          "PowerRestorePolicy", powerRestorePolicy,
          "PowerMode", powerMode,
          "HostWatchdogTimer/FunctionEnabled", wdtEnable,
          "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
          "Boot/BootSourceOverrideTarget", bootSource,
          "Boot/BootSourceOverrideMode", bootType,
          "Boot/BootSourceOverrideEnabled", bootEnable,
          "Boot/BootOrder", bootOrder,
          "Boot/BootNext", bootNext,
          "Boot/AutomaticRetryConfig", bootAutomaticRetry,
          "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
          "IdlePowerSaver/Enabled", ipsEnable,
          "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
          "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
          "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
          "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime
#ifdef ENABLE_REDFISH_CONFIGURE_IFS
          , "Oem/Google/CpuIfsPatternBase64", cpuIfsPatternBase64
#endif
          )) {
      return;
  }
  // clang-format on

  redfish::system_utils::getSystemInformation(
      asyncResp, systemName,
      [systemName, locationIndicatorActive = std::move(locationIndicatorActive),
       indicatorLed = std::move(indicatorLed), assetTag = std::move(assetTag),
       powerRestorePolicy = std::move(powerRestorePolicy),
       powerMode = std::move(powerMode), wdtEnable = std::move(wdtEnable),
       wdtTimeOutAction = std::move(wdtTimeOutAction),
       bootSource = std::move(bootSource), bootType = std::move(bootType),
       bootEnable = std::move(bootEnable), bootOrder = std::move(bootOrder),
       bootNext = std::move(bootNext),
       bootAutomaticRetry = std::move(bootAutomaticRetry),
       bootTrustedModuleRequired = std::move(bootTrustedModuleRequired),
       ipsEnable = std::move(ipsEnable), ipsEnterUtil = std::move(ipsEnterUtil),
       ipsEnterTime = std::move(ipsEnterTime),
       ipsExitUtil = std::move(ipsExitUtil),
       ipsExitTime = std::move(ipsExitTime),
       cpuIfsPatternBase64 = std::move(cpuIfsPatternBase64)](
          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
          const std::string& objectPath) {
        const bool multiHost = !objectPath.empty();
        asyncResp->res.addHeader(boost::beast::http::field::link,
                                 "</redfish/v1/JsonSchemas/ComputerSystem/"
                                 "ComputerSystem.json>; rel=describedby");

        asyncResp->res.result(boost::beast::http::status::no_content);

        if (assetTag) {
          setAssetTag(asyncResp, *assetTag);
        }

        if (wdtEnable || wdtTimeOutAction) {
          setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
        }

        if (bootSource || bootType || bootEnable || bootOrder) {
          setBootProperties(asyncResp, bootSource, bootType, bootEnable,
                            bootOrder, systemName, multiHost);
        }
        if (bootNext) {
          std::shared_ptr<milotic_tlbmc::SystemRegistry> registry =
              managedStore::GetManagedObjectStore()->GetSystemRegistry();
          if (!registry) {
            messages::internalError(asyncResp->res);
            return;
          }
          absl::Status status = registry->SetBootNext(systemName, *bootNext);
          if (!status.ok()) {
            BMCWEB_LOG_ERROR << "Failed to set BootNext: " << status;
            messages::internalError(asyncResp->res);
            return;
          }
        }
        if (bootAutomaticRetry) {
          setAutomaticRetry(asyncResp, *bootAutomaticRetry);
        }

        if (bootTrustedModuleRequired) {
          setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
        }

        if (locationIndicatorActive) {
          setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
        }

        if (indicatorLed) {
          setIndicatorLedState(asyncResp, *indicatorLed);
          asyncResp->res.addHeader(boost::beast::http::field::warning,
                                   "299 - \"IndicatorLED is deprecated. Use "
                                   "LocationIndicatorActive instead.\"");
        }

        if (powerRestorePolicy) {
          setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
        }

        if (powerMode) {
          setPowerMode(asyncResp, *powerMode);
        }

        if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
            ipsExitTime) {
          setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
                            ipsExitUtil, ipsExitTime);
        }

#ifdef ENABLE_REDFISH_CONFIGURE_IFS
        if (cpuIfsPatternBase64) {
          std::shared_ptr<milotic_tlbmc::SystemRegistry> registry =
              managedStore::GetManagedObjectStore()->GetSystemRegistry();
          if (!registry) {
            messages::internalError(asyncResp->res);
            return;
          }
          absl::Status status =
              registry->SetIfsPattern(systemName, *cpuIfsPatternBase64);
          if (status.code() == absl::StatusCode::kInvalidArgument) {
            messages::propertyValueFormatError(
                asyncResp->res, *cpuIfsPatternBase64,
                "Oem/Google/CpuIfsPatternBase64");
            return;
          }
          if (!status.ok()) {
            messages::internalError(asyncResp->res);
            return;
          }
        }
#endif
      });
}

inline void handleGetBootNumber(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  asyncResp->res.addHeader(boost::beast::http::field::link,
                           "</redfish/v1/JsonSchemas/GoogleBootNumber/"
                           "GoogleBootNumber.json>; rel=describedby");

  redfish::system_utils::getSystemInformation(
      asyncResp, systemName,
      [systemName](const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                   const std::string& systemPath) {
        getBootNumber(asyncResp, systemName, systemPath);
      });
}

inline void handleGetBareMetalInstance(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  asyncResp->res.addHeader(boost::beast::http::field::link,
                           "</redfish/v1/JsonSchemas/GoogleBareMetalInstance/"
                           "GoogleBareMetalInstance.json>; rel=describedby");

  getBMInstance(asyncResp, systemName);
}

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

  asyncResp->res.addHeader(boost::beast::http::field::link,
                           "</redfish/v1/JsonSchemas/GoogleBareMetalInstance/"
                           "GoogleBareMetalInstance.json>; rel=describedby");
  std::optional<std::string> bmiAssetTag;
  std::optional<std::string> bmiBoardSerialNumber;
  std::optional<std::string> bmiFamily;
  std::optional<std::string> bmiProductName;
  std::optional<std::string> bmiSKU;
  std::optional<std::string> bmiSystemSerialNumber;
  std::optional<std::string> bmiUUID;

  // clang-format off
    if (!json_util::readJsonPatch(
        req, asyncResp->res,
        "AssetTag", bmiAssetTag,
        "BoardSerialNumber", bmiBoardSerialNumber,
        "Family", bmiFamily,
        "ProductName", bmiProductName,
        "SKU", bmiSKU,
        "SystemSerialNumber", bmiSystemSerialNumber,
        "UUID", bmiUUID))
    {
        return;
    }
  // clang-format on
  asyncResp->res.result(boost::beast::http::status::no_content);
  if (bmiAssetTag || bmiBoardSerialNumber || bmiFamily || bmiProductName ||
      bmiSKU || bmiSystemSerialNumber || bmiUUID) {
    setBMInstance(asyncResp, systemName, bmiAssetTag.value_or(""),
                  bmiBoardSerialNumber.value_or(""), bmiFamily.value_or(""),
                  bmiProductName.value_or(""), bmiSKU.value_or(""),
                  bmiSystemSerialNumber.value_or(""), bmiUUID.value_or(""));
  }
}

/**
 * Systems derived class for delivering Computer Systems Schema.
 */
inline void requestRoutesSystems(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
      .privileges(redfish::privileges::headComputerSystem)
      .methods(boost::beast::http::verb::head)(
          std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
  /**
   * Functions triggers appropriate requests on DBus
   */
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
      .privileges(redfish::privileges::getComputerSystem)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetComputerSystemCollection, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
      .privileges(redfish::privileges::patchComputerSystem)
      .methods(boost::beast::http::verb::patch)(
          std::bind_front(handlePatchComputerSystemCollection, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Oem/Google/BareMetalInstance/")
      .privileges(redfish::privileges::getComputerSystem)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetBareMetalInstance, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Oem/Google/BareMetalInstance/")
      .privileges(redfish::privileges::patchComputerSystem)
      .methods(boost::beast::http::verb::patch)(
          std::bind_front(handlePatchBareMetalInstance, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Oem/Google/BootNumber/")
      .privileges(redfish::privileges::getComputerSystem)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetBootNumber, std::ref(app)));

#ifdef ENABLE_REDFISH_CONFIGURE_IFS
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/Actions/Oem/"
               "GoogleComputerSystem.ResetCpuIfsPattern")
      .privileges(redfish::privileges::postComputerSystem)
      .methods(boost::beast::http::verb::post)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& systemName) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }
            redfish::system_utils::getSystemInformation(
                asyncResp, systemName,
                [systemName](
                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                    const std::string& /*objectPath*/) {
                  std::shared_ptr<milotic_tlbmc::SystemRegistry> registry =
                      managedStore::GetManagedObjectStore()
                          ->GetSystemRegistry();
                  if (!registry) {
                    messages::internalError(asyncResp->res);
                    return;
                  }
                  absl::Status status = registry->ResetIfsPattern(systemName);
                  if (!status.ok()) {
                    messages::internalError(asyncResp->res);
                    return;
                  }
                  messages::success(asyncResp->res);
                });
          });
#endif
}

inline void handleSystemCollectionResetActionHead(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  asyncResp->res.addHeader(
      boost::beast::http::field::link,
      "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
}

inline void createResetActionInfoResponse(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  asyncResp->res.addHeader(
      boost::beast::http::field::link,
      "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");

  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/" + systemName + "/ResetActionInfo";
  asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
  asyncResp->res.jsonValue["Name"] = "Reset Action Info";
  asyncResp->res.jsonValue["Id"] = "ResetActionInfo";

  nlohmann::json::array_t parameters;
  nlohmann::json::object_t parameter;

  parameter["Name"] = "ResetType";
  parameter["Required"] = true;
  parameter["DataType"] = "String";
  parameter["Delay"] = "Number";
  nlohmann::json::array_t allowableValues;
  allowableValues.emplace_back("On");
  allowableValues.emplace_back("ForceOff");
  allowableValues.emplace_back("ForceOn");
  allowableValues.emplace_back("ForceRestart");
  allowableValues.emplace_back("GracefulRestart");
  allowableValues.emplace_back("GracefulShutdown");
  allowableValues.emplace_back("PowerCycle");
  allowableValues.emplace_back("Nmi");
#ifdef BMCWEB_ENABLE_REALLY_GRACEFUL_SHUTDOWN
  allowableValues.emplace_back("ReallyGracefulShutDownTechDebt");
#endif  // BMCWEB_ENABLE_REALLY_GRACEFUL_SHUTDOWN
  parameter["AllowableValues"] = std::move(allowableValues);
  parameters.emplace_back(std::move(parameter));

  nlohmann::json::object_t delayParameter;
  delayParameter["Name"] = "Delay";
  delayParameter["Required"] = false;
  delayParameter["DataType"] = "Number";
  parameters.emplace_back(std::move(delayParameter));
  asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
}

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

  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/", 0, systemInterfaces, requestContext,
      [asyncResp, systemName](const boost::system::error_code& ec,
                              const std::vector<std::string>& objects) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error";
          messages::internalError(asyncResp->res);
          return;
        }
        system_utils::findSystemPathAndTriggerCallback(
            asyncResp, systemName, objects,
            [systemName](const std::shared_ptr<bmcweb::AsyncResp>& resp,
                         const std::string& /*objectPath*/) {
              createResetActionInfoResponse(resp, systemName);
            });
      });
}

/**
 * SystemResetActionInfo derived class for delivering Computer Systems
 * ResetType AllowableValues using ResetInfo schema.
 */
inline void requestRoutesSystemResetActionInfo(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
      .privileges(redfish::privileges::headActionInfo)
      .methods(boost::beast::http::verb::head)(std::bind_front(
          handleSystemCollectionResetActionHead, std::ref(app)));
  /**
   * Functions triggers appropriate requests on DBus
   */
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
      .privileges(redfish::privileges::getActionInfo)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetSystemResetActionInfo, std::ref(app)));
}

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

#ifdef BMCWEB_ENABLE_REDFISH_BOOT_TIME
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/", 0, systemInterfaces, requestContext,
      [asyncResp, systemName](const boost::system::error_code& ec,
                              const std::vector<std::string>& objects) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "[handleHostBootTimeDataGet] failed to get "
                              "number of systems from dbus.";
          messages::internalError(asyncResp->res);
          return;
        }

        auto status =
            boottime::PopulateHostData(asyncResp, systemName, objects);
        if (!status.ok()) {
          BMCWEB_LOG_ERROR << status.message();
          messages::internalError(asyncResp->res);
          return;
        }
      });
#else
  std::string oDataId =
      absl::StrCat("/redfish/v1/Systems/", systemName, "/Oem/Google/BootTime");
  boottime::PopulateDisabledResponse(asyncResp, oDataId);
#endif
}

inline void requestRoutesHostBootTime(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Oem/Google/BootTime/")
      .privileges(redfish::privileges::getComputerSystemCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleHostBootTimeDataGet, std::ref(app)));
}
}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_SYSTEMS_H_
