/*
// Copyright (c) 2018 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
#pragma once

#include "bm_config.h"
#include "bmcweb_config.h"

#include "app.hpp"
#include "dbus_utility.hpp"
#include "health.hpp"
#include "hypervisor_system.hpp"
#include "led.hpp"
#include "managed_store.hpp"
#include "pcie.hpp"
#include "query.hpp"
#include "redfish_util.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/boot_time_utils.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/json_utils.hpp"
#include "utils/sw_utils.hpp"
#include "utils/time_utils.hpp"

#include <boost/container/flat_map.hpp>
#include <boost/system/error_code.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/message/types.hpp>
#include <sdbusplus/unpack_properties.hpp>

#include <array>
#include <filesystem>
#include <iomanip>
#include <string_view>
#include <variant>

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

namespace redfish
{

const static 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)
{
    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](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
            for (const auto& connection : connectionNames)
            {
                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](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);
                        });

                        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;
                        });
                    }
                }
                break;
            }
        }
    });
}

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";
        messages::internalError(aResp->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, "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 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)
{
    BMCWEB_LOG_DEBUG << "Get boot information.";

    getBootOverrideSource(aResp);
    getBootOverrideType(aResp);
    getBootOverrideEnable(aResp);
}

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";
        messages::internalError(aResp->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, "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_,
                [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_,
        [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_,
        [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_,
        [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_,
        [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_,
        [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.
 *
 * @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)
{
    BMCWEB_LOG_DEBUG << "Set boot information.";

    setBootModeOrSource(aResp, bootSource);
    setBootType(aResp, bootType);
    setBootEnable(aResp, bootEnable);
}

/**
 * @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_,
                [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_,
        [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_,
        [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_,
                [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_,
                [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_,
                [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";
}

/**
 * @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_,
                    [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_,
                    [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_,
                    [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_,
                    [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_,
                    [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 there are less than 2 Item.Systems assume singlehost
        if (objects.size() < 2)
        {
            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();
    });

    dbus_utils::getProperty<std::string>(
        "xyz.openbmc_project.Settings",
        "/xyz/openbmc_project/network/hypervisor",
        "xyz.openbmc_project.Network.SystemConfiguration", "HostName", context,
        [asyncResp](const boost::system::error_code& ec2,
                    const std::string& /*hostName*/) {
        if (!ec2)
        {
            BMCWEB_LOG_DEBUG << "Hypervisor is available";
            nlohmann::json::object_t hypervisor;
            hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
            asyncResp->res.jsonValue["Members"].push_back(
                std::move(hypervisor));
            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_, [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_,
        [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"
    if (resetType == "ReallyGracefulShutDownTechDebt")
    {
        return SystemResetCommand{
            .command =
                "xyz.openbmc_project.State.Host.Transition.ReallyGracefulShutDown",
            .hostCommand = true};
    }
    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;
        }
        // If there are less than 2 Item.Systems assume singlehost
        if (objects.size() < 2)
        {
            if (systemName != "system")
            {
                messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                           systemName);
                return;
            }
            sendSystemResetAction(req, asyncResp, "", systemName);
            return;
        }
        // Otherwise list all systems
        for (const auto& object : objects)
        {
            std::string objectName = object.substr(object.rfind('/') + 1);
            // Found system object
            if (systemName == objectName)
            {
                sendSystemResetAction(req, asyncResp, object, systemName);
                return;
            }
        }

        // Could not find system object
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   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"] = "/redfish/v1/Systems/" + systemName;
    asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
        "/redfish/v1/Systems/" + systemName + "/Actions/ComputerSystem.Reset";
    asyncResp->res
        .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
        "/redfish/v1/Systems/" + systemName + "/ResetActionInfo";
    asyncResp->res.jsonValue["Processors"]["@odata.id"] =
        "/redfish/v1/Systems/" + systemName + "/Processors";
    asyncResp->res.jsonValue["Storage"]["@odata.id"] =
        "/redfish/v1/Systems/" + systemName + "/Storage";
    getBMReady(asyncResp);
    if constexpr (enableGoogleBaremetal)
    {
        asyncResp->res
            .jsonValue["Actions"]["Oem"]["Google"]
                      ["#GoogleComputerSystem.BootGuestOS"]["target"] =
            "/redfish/v1/Systems/" + systemName +
            "/Actions/Oem/GoogleComputerSystem.BootGuestOS";
        asyncResp->res.jsonValue["Actions"]["Oem"]["Google"]
                                ["#GoogleComputerSystem.BootGuestOS"]
                                ["@Redfish.ActionInfo"] =
            "/redfish/v1/Systems/" + systemName +
            "/Oem/Google/BootGuestOSActionInfo";
        asyncResp->res
            .jsonValue["Oem"]["Google"]["BareMetalInstance"]["@odata.id"] =
            "/redfish/v1/Systems/" + systemName +
            "/Oem/Google/BareMetalInstance";
        getNERFStatus(asyncResp, systemName);
    }
    asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
        "/redfish/v1/Systems/" + systemName + "/LogServices";
    asyncResp->res.jsonValue["Memory"]["@odata.id"] =
        "/redfish/v1/Systems/" + systemName + "/Memory";

    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");

    // 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"] =
            uint64_t(0);
        asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
            "Disabled";
        asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
            "/redfish/v1/Systems/system/FabricAdapters";

        asyncResp->res.jsonValue["Bios"]["@odata.id"] =
            "/redfish/v1/Systems/system/Bios";

        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));

#ifdef BMCWEB_ENABLE_KVM
        // Fill in GraphicalConsole info
        asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
        asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
            4;
        asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
            nlohmann::json::array_t({"KVMIP"});

#endif // BMCWEB_ENABLE_KVM

        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);
        getBootProperties(asyncResp);
        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);
    }
#ifdef BMCWEB_ENABLE_REDFISH_BOOT_TIME
    asyncResp->res.jsonValue["Oem"]["Google"]["BootTime"]["@odata.id"] =
        "/redfish/v1/Systems/" + systemName + "/Oem/Google/BootTime";
#endif
}

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

    if (systemName == "hypervisor")
    {
        handleHypervisorSystemGet(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;
        }

        // If there are less than 2 Item.Systems assume singlehost
        if (objects.size() < 2)
        {
            if (systemName != "system")
            {
                messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                           systemName);
                return;
            }
            handleComputerSystem(asyncResp, "", systemName, false);
            return;
        }
        // Otherwise find system
        for (const auto& object : objects)
        {
            std::string objectName = object.substr(object.rfind('/') + 1);
            // Found system object
            if (systemName == objectName)
            {
                handleComputerSystem(asyncResp, object, systemName, true);
                return;
            }
        }

        // Could not find system object
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   systemName);
    });
}

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;
    }
    if (systemName != "system")
    {
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   systemName);
        return;
    }

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

    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::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;

    // 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/AutomaticRetryConfig", bootAutomaticRetry,
                    "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
                    "IdlePowerSaver/Enabled", ipsEnable,
                    "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
                    "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
                    "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
                    "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
            {
                return;
            }
    // clang-format on

    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)
    {
        setBootProperties(asyncResp, bootSource, bootType, bootEnable);
    }
    if (bootAutomaticRetry)
    {
        setAutomaticRetry(asyncResp, *bootAutomaticRetry);
    }

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

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

    // TODO (Gunnar): Remove IndicatorLED after enough time has
    // passed
    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);
    }
}

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

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");
    allowableValues.emplace_back("ReallyGracefulShutDownTechDebt");
    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;
    }

    if (systemName == "hypervisor")
    {
        handleHypervisorResetActionGet(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;
        }
        // If there are less than 2 Item.Systems assume singlehost
        if (objects.size() < 2)
        {
            if (systemName != "system")
            {
                messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                           systemName);
                return;
            }
            createResetActionInfoResponse(asyncResp, systemName);
            return;
        }
        // Otherwise list all systems
        for (const auto& object : objects)
        {
            std::string objectName = object.substr(object.rfind('/') + 1);
            // Found system object
            if (systemName == objectName)
            {
                createResetActionInfoResponse(asyncResp, systemName);
                return;
            }
        }

        // Could not find system object
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   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)));
}
/**
 * @brief Parses a system name to determine its corresponding host index.
 *
 * This function validates and extracts a host index from a system name string,
 * adjusting its behavior based on whether the system is in a multihost
 * configuration.
 *
 * In a multihost configuration (`multihost` is `true`), this function expects
 * the system name to be in the format "system<N>", where <N> is a 1-based
 * integer (e.g., "system1", "system2"). On success, the `index` parameter
 * is set to the corresponding 0-based index (N-1).
 *
 * In a single-host configuration (`multihost` is `false`), this function
 * expects the system name to be exactly "system". On success, the `index`
 * parameter is set to `0`.
 *
 * @param systemName The system name string to parse (e.g., "system1").
 * @param multihost  A flag indicating if the system is in a
 *                        multihost environment.
 * @param index      An output parameter. If the function returns `true`,
 *                        this will contain the parsed 0-based host index.
 *                        The value is `-1` if the function returns `false`.
 *
 * @return `true` if the system name was successfully parsed and the index was
 *         set, `false` otherwise.
 */
inline bool parseSystemNameToIndex(const std::string_view systemName,
                                   const bool multihost, int& index)
{
    index = -1;
    if (!multihost)
    {
        if (systemName == "system")
        {
            index = 0;
            return true; // Assume the system name should just be "system" in
                         // single host.
        }
        return false;
    }

    constexpr std::string_view prefix = "system";

    if (systemName.size() < prefix.size() ||
        systemName.substr(0, prefix.size()) != prefix)
    {
        return false; // Handle cases not start with "system" prefix in
                      // multihost mode
    }

    std::string_view number_part = systemName.substr(prefix.length());

    if (number_part.empty())
    {
        return false; // Handle cases like just "system" in multihost mode
    }

    int number = 0;
    const auto result = std::from_chars(
        number_part.data(), number_part.data() + number_part.size(), number);

    if (result.ec == std::errc() &&
        result.ptr == number_part.data() + number_part.size())
    {
        if (number > 0)
        {
            index = number - 1; // System names are 1-based, index is 0-based
            return true;
        }
    }

    return false; // Parsing failed or number was not a positive integer
}

inline void populateHostBootTimeData(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName,
    const std::shared_ptr<boot_time_monitor::api::IBoottimeApi>& api,
    const boot_time_monitor::NodeConfig nodeConfig)
{
    boot_time_utils::PopulateDefaultBootTimeProperties(asyncResp);
    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/Systems/" + systemName + "/Oem/Google/BootTime";

    std::shared_ptr<std::vector<boot_time_utils::Checkpoint>> hostCheckpoints =
        std::make_shared<std::vector<boot_time_utils::Checkpoint>>();
    std::shared_ptr<std::vector<boot_time_utils::Duration>> hostDurations =
        std::make_shared<std::vector<boot_time_utils::Duration>>();
    std::shared_ptr<std::vector<boot_time_utils::Checkpoint>> bmcCheckpoints =
        std::make_shared<std::vector<boot_time_utils::Checkpoint>>();
    std::shared_ptr<bool> hostIsRebooting = std::make_shared<bool>(false);

    std::shared_ptr<int> waitingForLoadingData = std::make_shared<int>(3);

    std::function<void()> dbusSuccessCallback = [asyncResp, hostCheckpoints,
                                                 hostDurations, hostIsRebooting,
                                                 waitingForLoadingData]() {
        --(*waitingForLoadingData);
        if (*waitingForLoadingData == 0)
        {
            boot_time_utils::GetHostBreakdownStages(asyncResp, hostCheckpoints,
                                                    hostDurations);
            boot_time_utils::PopulateDurationInResponse(asyncResp,
                                                        hostDurations);
            boot_time_utils::GetHostRebootFlow(asyncResp, hostCheckpoints);
            boot_time_utils::PopulateTotalTimeInResponse(
                asyncResp, hostCheckpoints, hostDurations);
            boot_time_utils::PopulateStatPowerSourceInResponse(asyncResp,
                                                               hostCheckpoints);
            boot_time_utils::PopulateStatIsRebootingInResponse(asyncResp,
                                                               hostIsRebooting);
        }
    };

    boot_time_utils::GetBootTimeCheckpoints(api, nodeConfig, hostCheckpoints,
                                            dbusSuccessCallback);
    boot_time_utils::GetBootTimeDurations(api, nodeConfig, hostDurations,
                                          dbusSuccessCallback);
    boot_time_utils::GetIsRebooting(api, nodeConfig, hostIsRebooting,
                                    dbusSuccessCallback);
}

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

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

        int systemIndex;
        // If there are less than 2 Item.Systems assume singlehost
        if (objects.size() < 2)
        {
            if (!parseSystemNameToIndex(systemName, false, systemIndex))
            {
                messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                           systemName);
                return;
            }
        }
        else
        {
            if (!parseSystemNameToIndex(systemName, true, systemIndex))
            {
                messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                           systemName);
                return;
            }
        }

        boot_time_monitor::NodeConfig nc = {
            .node_name = "host" + std::to_string(systemIndex),
            .tag = std::string(boot_time_monitor::kBootTimeTagHost)};

        std::shared_ptr<boot_time_monitor::api::BoottimeApi> api =
            std::make_shared<boot_time_monitor::api::BoottimeApi>();

        absl::Status status = api->RegisterNode(nc);
        switch (status.code())
        {
            case absl::StatusCode::kOk:
            case absl::StatusCode::kAlreadyExists:
            {
                populateHostBootTimeData(asyncResp, systemName, api, nc);
                break;
            }
            case absl::StatusCode::kInternal:
            default:
            {
                BMCWEB_LOG_ERROR
                    << "Failed to register " << nc.node_name
                    << " node due to internal error: " << status.ToString();
                messages::internalError(asyncResp->res);
                break;
            }
        }
    });
}

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
