/*
// 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"}};

/**
 * @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](
            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;
        }

        getHostState(asyncResp, systemObjectPath, objects);
        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);
        // Enabled boot time only for single host
#ifdef BMCWEB_ENABLE_REDFISH_BOOT_TIME
        asyncResp->res.jsonValue["Oem"]["Google"]["BootTime"]["@odata.id"] =
            "/redfish/v1/Systems/system/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)));
}

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

    // only for single host
    if (systemName != "system")
    {
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   systemName);
        return;
    }

    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>(4);
    std::shared_ptr<bool> errorOccurred = std::make_shared<bool>(false);

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

    boot_time_utils::GetBootTimeCheckpoints(asyncResp, "host0", hostCheckpoints,
                                            dbusSuccessCallback,
                                            dbusErrCallback);
    boot_time_utils::GetBootTimeDurations(asyncResp, "host0", hostDurations,
                                          dbusSuccessCallback, dbusErrCallback);
    boot_time_utils::GetBootTimeCheckpoints(
        asyncResp, "bmc", bmcCheckpoints, dbusSuccessCallback, dbusErrCallback);
    boot_time_utils::GetIsRebooting(asyncResp, "host0", hostIsRebooting,
                                    dbusSuccessCallback, dbusErrCallback);
}

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
