/*
// 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 "boottime.hpp"
#include "dbus_utility.hpp"
#include "dbus_utils.hpp"
#include "health.hpp"
#include "hypervisor_system.hpp"
#include "json_utils.hpp"
#include "led.hpp"
#include "managed_store.hpp"
#include "pcie.hpp"
#include "query.hpp"
#include "redfish_util.hpp"
#include "registries/privilege_registry.hpp"
#include "sw_utils.hpp"
#include "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 <charconv>
#include <filesystem>
#include <iomanip>
#include <string_view>
#include <variant>

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

namespace redfish
{

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

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

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

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

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

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

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

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

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

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

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

inline void getProcessorProperties(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
        properties)
{

    BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";

    // TODO: Get Model

    const uint16_t* coreCount = nullptr;

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

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

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

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

/*
 * @brief Get ProcessorSummary fields
 *
 * @param[in] aResp Shared pointer for completing asynchronous calls
 * @param[in] service dbus service for Cpu Information
 * @param[in] path dbus path for Cpu
 *
 * @return None.
 */
inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                                const std::string& service,
                                const std::string& path)
{

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

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

    managedStore::ManagedObjectStoreContext context(aResp);

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

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

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

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

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

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

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

#ifdef HEALTH_POPULATE
            systemHealth->children.emplace_back(memoryHealth);
            systemHealth->children.emplace_back(cpuHealth);
#endif

            // This is not system, so check if it's cpu, dimm, UUID or
            // BiosVer
            for (const auto& connection : connectionNames)
            {
                for (const auto& interfaceName : connection.second)
                {
                    if (interfaceName ==
                        "xyz.openbmc_project.Inventory.Item.Dimm")
                    {
                        BMCWEB_LOG_DEBUG
                            << "Found Dimm, now get its properties.";

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

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

                            const size_t* memorySizeInKB = nullptr;

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

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

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

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

                        getProcessorSummary(aResp, connection.first, path);

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

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

                            const std::string* uUID = nullptr;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

inline void populateHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                              const std::string& service,
                              const std::string& path)
{

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

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

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

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

    // Objects should never be empty in a multi-host system
    if (objects.empty())
    {
        BMCWEB_LOG_ERROR << "Host has no Power Control Objects";
        messages::internalError(aResp->res);
        return;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        processBootOverrideEnable(aResp, bootOverrideEnable);
    });
}

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

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

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

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

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

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

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

/**
 * @brief Sets boot order to oem-bios-setting file
 *
 * @param[in] aResp     Shared pointer for generating response message.
 * @param[in] bootOrder   The boot order from incoming RF request.
 *
 * @return None.
 */
inline void setBootOrder(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::vector<std::string>& bootOrder,
    const std::string& biosSettingFile = "/var/google/oem_bios_setting")
{
    // Create a temporary file to ensure atomic write
    std::string tempFile = biosSettingFile + ".tmp";
    std::ofstream file(tempFile, std::ios::binary | std::ios::trunc);
    if (!file.is_open())
    {
        BMCWEB_LOG_ERROR << "Failed to open " << tempFile << " for writing.";
        messages::internalError(aResp->res);
        return;
    }

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

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

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

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

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

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

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

    getBootOverrideSource(aResp);
    getBootOverrideType(aResp);
    getBootOverrideEnable(aResp);
    getBootOrder(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.
 * @param[in] bootOrder  The boot order from incoming RF request.
 *
 * @return Integer error code.
 */

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

    setBootModeOrSource(aResp, bootSource);
    setBootType(aResp, bootType);
    setBootEnable(aResp, bootEnable);
    if (bootOrder)
    {
        setBootOrder(aResp, *bootOrder);
    }
}

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

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

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

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

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

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

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

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

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

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

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

        if (ipsEnable)
        {
            managedStore::GetManagedObjectStore()
                ->PostDbusCallToIoContextThreadSafe(
                    aResp->strand_,
                    [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";
    asyncResp->res.jsonValue["Bios"]["@odata.id"] =
        "/redfish/v1/Systems/" + systemName + "/Bios";
    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);
    }

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

    asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
        "/redfish/v1/Systems/" + systemName + "/LogServices";
    asyncResp->res.jsonValue["Memory"]["@odata.id"] =
        "/redfish/v1/Systems/" + systemName + "/Memory";
    asyncResp->res.jsonValue["Oem"]["Google"]["BootTime"]["@odata.id"] =
        "/redfish/v1/Systems/" + systemName + "/Oem/Google/BootTime";

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

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

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

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

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

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

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

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

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

    getPCIeDeviceList(asyncResp, systemName, "PCIeDevices");

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

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::vector<std::string>> bootOrder;
    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/BootOrder", bootOrder,
                    "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 || bootOrder)
    {
        setBootProperties(asyncResp, bootSource, bootType, bootEnable,
                          bootOrder);
    }
    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
    handleGetBootNumber(App& app, const crow::Request& req,
                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                        const std::string& systemName)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    asyncResp->res.addHeader(
        boost::beast::http::field::link,
        "</redfish/v1/JsonSchemas/GoogleBootNumber/GoogleBootNumber.json>; rel=describedby");

    getBootNumber(asyncResp, systemName);
}

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

    getBMInstance(asyncResp, systemName);
}

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

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

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

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

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

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

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

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

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

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

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

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