/*
// 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 "app.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "external_storer.hpp"
#include "health.hpp"
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/collection.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/hex_utils.hpp"
#include "utils/json_utils.hpp"
#include "utils/location_utils.hpp"
#include "utils/system_utils.hpp"

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

#include <algorithm>
#include <array>
#include <cstdint>
#include <limits>
#include <string_view>
#include <unordered_map>

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

namespace redfish
{

using resourceIdToSubtreeRespMapType =
    std::unordered_map<std::string,
                       std::pair<std::string, dbus::utility::MapperServiceMap>>;
using ManagedObjectByServiceMap =
    std::unordered_map<std::string, dbus::utility::ManagedObjectType>;

constexpr std::array<std::string_view, 2> processorInterfaces = {
    "xyz.openbmc_project.Inventory.Item.Cpu",
    "xyz.openbmc_project.Inventory.Item.Accelerator"};

constexpr std::array<std::string_view, 1> subProcessorCoreInterfaces = {
    "xyz.openbmc_project.Inventory.Item.CpuCore"};

constexpr std::array<std::string_view, 1> subProcessorThreadInterfaces = {
    "xyz.openbmc_project.Inventory.Item.CpuThread"};

inline void getSubProcessorThreadCollectionWithExpand(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const nlohmann::json::json_pointer& jsonPtr, uint8_t expandLevel,
    const std::string& processorId, const std::string& coreId,
    const std::string& corePath,
    const dbus::utility::MapperGetSubTreeResponse& subtree,
    const ManagedObjectByServiceMap& managedObjectsMap);

inline void getSubProcessorCoreCollectionWithExpand(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const nlohmann::json::json_pointer& jsonPtr, uint8_t expandLevel,
    const std::string& processorId, const std::string& cpuPath,
    const dbus::utility::MapperGetSubTreeResponse& subtree,
    const ManagedObjectByServiceMap& managedObjectsMap);

inline void getProcessorCollectionWithExpand(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const dbus::utility::MapperGetSubTreeResponse& subtree,
    const ManagedObjectByServiceMap& managedObjectsMap, uint8_t expandLevel,
    const std::string& systempath);

inline void handleGetCpuCoreThreadMetrics(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const nlohmann::json::json_pointer& jsonPtr, const std::string& cpuArg,
    const std::string& coreArg, const std::string& threadArg);

inline void
    handleGetCpuMetrics(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                        const nlohmann::json::json_pointer& jsonPtr,
                        const std::string& cpuArg);

/**
 * @brief Returns a collection of dbus interfaces applicable to SubProcessor's
 * subtree.
 *
 * @param[in] expandLevel Requested expand level.
 *
 * @return Vector of strings capturing dbus interface names.
 */
inline std::vector<std::string>
    getInterfacesForSubProcessorSubtree(uint8_t expandLevel)
{
    std::vector<std::string> subProcessorSubtreeInterfaces = {
        subProcessorCoreInterfaces.begin(), subProcessorCoreInterfaces.end()};
    if (expandLevel > 0)
    {
        subProcessorSubtreeInterfaces.insert(
            subProcessorSubtreeInterfaces.end(),
            subProcessorThreadInterfaces.begin(),
            subProcessorThreadInterfaces.end());
        return subProcessorSubtreeInterfaces;
    }
    return subProcessorSubtreeInterfaces;
}

/**
 * @brief Returns a collection of dbus interfaces applicable to Processor's
 * subtree.
 *
 * @param[in] expandLevel Requested expand level.
 *
 * @return Vector of strings capturing dbus interface names.
 */
inline std::vector<std::string>
    getInterfacesForProcessorSubtree(uint8_t expandLevel)
{
    if (expandLevel > 0)
    {
        std::vector<std::string> processorSubtreeInterfaces =
            getInterfacesForSubProcessorSubtree(expandLevel - 1);
        processorSubtreeInterfaces.insert(processorSubtreeInterfaces.end(),
                                          processorInterfaces.begin(),
                                          processorInterfaces.end());
        return processorSubtreeInterfaces;
    }
    return {processorInterfaces.begin(), processorInterfaces.end()};
}

/**
 * @brief Fill out uuid info of a processor by
 * requesting data from the given D-Bus object.
 *
 * @param[in,out]   aResp           Async HTTP response.
 * @param[in]       objPath         D-Bus object to query.
 * @param[in]       interface       D-Bus interface to query.
 * @param[in]       jsonPtr         json pointer to index the response fields
 * @param[in]       managedObjects  Dbus objects with interfaces and properties.
 */
inline void
    getProcessorUUID(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                     const std::string& objPath, const std::string& interface,
                     const nlohmann::json::json_pointer& jsonPtr,
                     const dbus::utility::ManagedObjectType& managedObjects)
{
    BMCWEB_LOG_DEBUG << "Get Processor UUID";
    dbus::utility::DBusPropertiesMap properties;
    dbus_utils::getPropertiesFromManagedObjects(managedObjects, objPath,
                                                interface, properties);

    const std::string* property = nullptr;

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

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

    if (property != nullptr)
    {
        aResp->res.jsonValue[jsonPtr]["UUID"] = *property;
    }
}

/**
 * @brief Populates Cpu information using given dbus properties.
 *
 * @param[in] aResp             Async HTTP response.
 * @param[in] jsonPtr           json pointer to index the response fields.
 * @param[in] dbusProperties    DBusPropertiesMap to parse for Cpu data.
 *
 * @return void
 */
inline void getCpuDataFromDbusProperties(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const nlohmann::json::json_pointer& jsonPtr,
    const dbus::utility::DBusPropertiesMap& dbusProperties)
{
    BMCWEB_LOG_DEBUG << "Get CPU resources from dbus properties.";

    // Set the default value of state
    aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled";
    aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";

    for (const auto& property : dbusProperties)
    {
        if (property.first == "Present")
        {
            const bool* cpuPresent = std::get_if<bool>(&property.second);
            if (cpuPresent == nullptr)
            {
                // Important property not in desired type
                messages::internalError(aResp->res);
                return;
            }
            if (!*cpuPresent)
            {
                // Slot is not populated
                aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
            }
        }
        else if (property.first == "Functional")
        {
            const bool* cpuFunctional = std::get_if<bool>(&property.second);
            if (cpuFunctional == nullptr)
            {
                messages::internalError(aResp->res);
                return;
            }
            if (!*cpuFunctional)
            {
                aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "Critical";
            }
        }
        else if (property.first == "CoreCount")
        {
            const uint16_t* coresCount =
                std::get_if<uint16_t>(&property.second);
            if (coresCount == nullptr)
            {
                messages::internalError(aResp->res);
                return;
            }
            aResp->res.jsonValue[jsonPtr]["TotalCores"] = *coresCount;
        }
        else if (property.first == "MaxSpeedInMhz")
        {
            const uint32_t* value = std::get_if<uint32_t>(&property.second);
            if (value != nullptr)
            {
                aResp->res.jsonValue[jsonPtr]["MaxSpeedMHz"] = *value;
            }
        }
        else if (property.first == "Socket")
        {
            const std::string* value =
                std::get_if<std::string>(&property.second);
            if (value != nullptr)
            {
                aResp->res.jsonValue[jsonPtr]["Socket"] = *value;
            }
        }
        else if (property.first == "ThreadCount")
        {
            const uint16_t* value = std::get_if<uint16_t>(&property.second);
            if (value != nullptr)
            {
                aResp->res.jsonValue[jsonPtr]["TotalThreads"] = *value;
            }
        }
        else if (property.first == "CoreEnable")
        {
            const uint16_t* value = std::get_if<uint16_t>(&property.second);
            if (value != nullptr)
            {
                aResp->res.jsonValue[jsonPtr]["TotalEnabledCores"] = *value;
            }
        }
        else if (property.first == "EffectiveFamily")
        {
            const uint16_t* value = std::get_if<uint16_t>(&property.second);
            if (value != nullptr && *value != 2)
            {
                aResp->res
                    .jsonValue[jsonPtr]["ProcessorId"]["EffectiveFamily"] =
                    "0x" + intToHexString(*value, 4);
            }
        }
        else if (property.first == "EffectiveModel")
        {
            const uint16_t* value = std::get_if<uint16_t>(&property.second);
            if (value == nullptr)
            {
                messages::internalError(aResp->res);
                return;
            }
            if (*value != 0)
            {
                aResp->res.jsonValue[jsonPtr]["ProcessorId"]["EffectiveModel"] =
                    "0x" + intToHexString(*value, 4);
            }
        }
        else if (property.first == "Id")
        {
            const uint64_t* value = std::get_if<uint64_t>(&property.second);
            if (value != nullptr && *value != 0)
            {
                aResp->res.jsonValue[jsonPtr]["ProcessorId"]
                                    ["IdentificationRegisters"] =
                    "0x" + intToHexString(*value, 16);
            }
        }
        else if (property.first == "Microcode")
        {
            const uint32_t* value = std::get_if<uint32_t>(&property.second);
            if (value == nullptr)
            {
                messages::internalError(aResp->res);
                return;
            }
            if (*value != 0)
            {
                aResp->res.jsonValue[jsonPtr]["ProcessorId"]["MicrocodeInfo"] =
                    "0x" + intToHexString(*value, 8);
            }
        }
        else if (property.first == "Step")
        {
            const uint16_t* value = std::get_if<uint16_t>(&property.second);
            if (value == nullptr)
            {
                messages::internalError(aResp->res);
                return;
            }
            if (*value != std::numeric_limits<uint16_t>::max())
            {
                aResp->res.jsonValue[jsonPtr]["ProcessorId"]["Step"] =
                    "0x" + intToHexString(*value, 4);
            }
        }
    }
}

/**
 * @brief Populates Cpu information using given dbus Managed Objects.
 *
 * @param[in] aResp         Async HTTP response.
 * @param[in] cpuId         Cpu identifier.
 * @param[in] objPath       Cpu dbus object path.
 * @param[in] interface     Cpu dbus interface name.
 * @param[in] jsonPtr       json pointer to index the response fields.
 * @param[in] dbusData      Dbus Managed Objects to parse for Cpu data.
 *
 * @return void
 */
inline void getCpuData(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                       const std::string& cpuId, const std::string& objPath,
                       const std::string& interface,
                       const nlohmann::json::json_pointer& jsonPtr,
                       const dbus::utility::ManagedObjectType& dbusData)
{
    BMCWEB_LOG_DEBUG << "Get Cpu data from managed objects for object "
                     << objPath;
    aResp->res.jsonValue[jsonPtr]["Id"] = cpuId;
    aResp->res.jsonValue[jsonPtr]["Name"] = "Processor";
    aResp->res.jsonValue[jsonPtr]["ProcessorType"] = "CPU";

    bool slotPresent = false;
    std::string corePath = objPath + "/core";
    size_t totalCores = 0;
    for (const auto& object : dbusData)
    {
        dbus::utility::DBusPropertiesMap properties;
        if (object.first.str == objPath)
        {
            dbus_utils::getPropertiesFromManagedObjects(dbusData, objPath,
                                                        interface, properties);
            getCpuDataFromDbusProperties(aResp, jsonPtr, properties);
        }
        else if (object.first.str.starts_with(corePath))
        {
            dbus_utils::getPropertiesFromManagedObjects(
                dbusData, object.first.str,
                "xyz.openbmc_project.Inventory.Item", properties);

            for (const auto& property : properties)
            {
                if (property.first != "Present")
                {
                    continue;
                }
                const bool* present = std::get_if<bool>(&property.second);
                if (present != nullptr && *present)
                {
                    slotPresent = true;
                    totalCores++;
                }
            }
        }
    }
    // In getCpuDataFromDbusProperties(), state and health are set based on the
    // present and functional status. If core count is zero, then it has a
    // higher precedence.
    if (slotPresent)
    {
        if (totalCores == 0)
        {
            // Slot is not populated, set status end return
            aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
            aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";
        }
        aResp->res.jsonValue[jsonPtr]["TotalCores"] = totalCores;
    }
}

/**
 * @brief Populates Cpu asset information using given dbus Managed Objects.
 *
 * @param[in] aResp             Async HTTP response.
 * @param[in] objPath           Cpu dbus object path.
 * @param[in] interface         Cpu dbus interface name.
 * @param[in] jsonPtr           json pointer to index the response fields.
 * @param[in] managedObjects    Dbus Managed Objects to parse for Cpu data.
 *
 * @return void
 */
inline void
    getCpuAssetData(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                    const std::string& objPath, const std::string& interface,
                    const nlohmann::json::json_pointer& jsonPtr,
                    const dbus::utility::ManagedObjectType& managedObjects)
{
    BMCWEB_LOG_DEBUG << "Get Cpu Asset Data";
    const std::string* serialNumber = nullptr;
    const std::string* model = nullptr;
    const std::string* manufacturer = nullptr;
    const std::string* partNumber = nullptr;
    const std::string* sparePartNumber = nullptr;

    dbus::utility::DBusPropertiesMap properties;
    dbus_utils::getPropertiesFromManagedObjects(managedObjects, objPath,
                                                interface, properties);

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

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

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

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

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

        // Otherwise would be unexpected.
        if (manufacturer->find("Intel") != std::string::npos)
        {
            aResp->res.jsonValue[jsonPtr]["ProcessorArchitecture"] = "x86";
            aResp->res.jsonValue[jsonPtr]["InstructionSet"] = "x86-64";
        }
        else if (manufacturer->find("IBM") != std::string::npos)
        {
            aResp->res.jsonValue[jsonPtr]["ProcessorArchitecture"] = "Power";
            aResp->res.jsonValue[jsonPtr]["InstructionSet"] = "PowerISA";
        }
    }

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

    if (sparePartNumber != nullptr && !sparePartNumber->empty())
    {
        aResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber;
    }
}

/**
 * @brief Populates Cpu revision data using given dbus Managed Objects.
 *
 * @param[in] aResp             Async HTTP response.
 * @param[in] objPath           Cpu dbus object path.
 * @param[in] interface         Cpu dbus interface name.
 * @param[in] jsonPtr           json pointer to index the response fields.
 * @param[in] managedObjects    Dbus Managed Objects to parse for Cpu data.
 *
 * @return void
 */
inline void
    getCpuRevisionData(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                       const std::string& objPath, const std::string& interface,
                       const nlohmann::json::json_pointer& jsonPtr,
                       const dbus::utility::ManagedObjectType& managedObjects)
{
    BMCWEB_LOG_DEBUG << "Get Cpu Revision Data";
    dbus::utility::DBusPropertiesMap properties;
    dbus_utils::getPropertiesFromManagedObjects(managedObjects, objPath,
                                                interface, properties);

    const std::string* version = nullptr;

    const bool success = sdbusplus::unpackPropertiesNoThrow(
        dbus_utils::UnpackErrorPrinter(), properties, "Version", version);

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

    if (version != nullptr)
    {
        aResp->res.jsonValue[jsonPtr]["Version"] = *version;
    }
}

/**
 * @brief Populates accelerator data using given dbus Managed Objects.
 *
 * @param[in] aResp             Async HTTP response.
 * @param[in] acclrtrId         Accelerator identifier.
 * @param[in] objPath           Accelerator dbus object path.
 * @param[in] interface         Accelerator dbus interface name.
 * @param[in] jsonPtr           json pointer to index the response fields.
 * @param[in] managedObjects    Dbus Managed Objects to parse.
 *
 * @return void
 */
inline void
    getAcceleratorData(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                       const std::string& acclrtrId, const std::string& objPath,
                       const std::string& interface,
                       const nlohmann::json::json_pointer& jsonPtr,
                       const dbus::utility::ManagedObjectType& managedObjects)
{
    BMCWEB_LOG_DEBUG
        << "Get available system Accelerator resources by service.";

    const bool* functional = nullptr;
    const bool* present = nullptr;

    dbus::utility::DBusPropertiesMap properties;
    dbus_utils::getPropertiesFromManagedObjects(managedObjects, objPath,
                                                interface, properties);

    const bool success = sdbusplus::unpackPropertiesNoThrow(
        dbus_utils::UnpackErrorPrinter(), properties, "Functional", functional,
        "Present", present);

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

    std::string state = "Enabled";
    std::string health = "OK";

    if (present != nullptr && !*present)
    {
        state = "Absent";
    }

    if (functional != nullptr && !*functional)
    {
        if (state == "Enabled")
        {
            health = "Critical";
        }
    }

    aResp->res.jsonValue[jsonPtr]["Id"] = acclrtrId;
    aResp->res.jsonValue[jsonPtr]["Name"] = "Processor";
    aResp->res.jsonValue[jsonPtr]["Status"]["State"] = state;
    aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = health;
    aResp->res.jsonValue[jsonPtr]["ProcessorType"] = "Accelerator";
}

// OperatingConfig D-Bus Types
using TurboProfileProperty = std::vector<std::tuple<uint32_t, size_t>>;
using BaseSpeedPrioritySettingsProperty =
    std::vector<std::tuple<uint32_t, std::vector<uint32_t>>>;
// uint32_t and size_t may or may not be the same type, requiring a dedup'd
// variant

/**
 * Fill out the HighSpeedCoreIDs in a Processor resource from the given
 * OperatingConfig D-Bus property.
 *
 * @param[in,out]   aResp               Async HTTP response.
 * @param[in]       jsonPtr     json pointer to index the response fields
 * @param[in]       baseSpeedSettings   Full list of base speed priority groups,
 *                                      to use to determine the list of high
 *                                      speed cores.
 */
inline void highSpeedCoreIdsHandler(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const nlohmann::json::json_pointer& jsonPtr,
    const BaseSpeedPrioritySettingsProperty& baseSpeedSettings)
{
    // The D-Bus property does not indicate which bucket is the "high
    // priority" group, so let's discern that by looking for the one with
    // highest base frequency.
    auto highPriorityGroup = baseSpeedSettings.cend();
    uint32_t highestBaseSpeed = 0;
    for (auto it = baseSpeedSettings.cbegin(); it != baseSpeedSettings.cend();
         ++it)
    {
        const uint32_t baseFreq = std::get<uint32_t>(*it);
        if (baseFreq > highestBaseSpeed)
        {
            highestBaseSpeed = baseFreq;
            highPriorityGroup = it;
        }
    }

    nlohmann::json& jsonCoreIds =
        aResp->res.jsonValue[jsonPtr]["HighSpeedCoreIDs"];
    jsonCoreIds = nlohmann::json::array();

    // There may not be any entries in the D-Bus property, so only populate
    // if there was actually something there.
    if (highPriorityGroup != baseSpeedSettings.cend())
    {
        jsonCoreIds = std::get<std::vector<uint32_t>>(*highPriorityGroup);
    }
}

/**
 * Fill out OperatingConfig related items in a Processor resource by requesting
 * data from the given D-Bus object.
 *
 * @param[in,out]   aResp           Async HTTP response.
 * @param[in]       cpuId           CPU D-Bus name.
 * @param[in]       objPath         D-Bus object to query.
 * @param[in]       interface       D-Bus interface to query.
 * @param[in]       jsonPtr         json pointer to index the response fields
 * @param[in]       managedObjects  Dbus objects with interfaces and properties.
 */
inline void
    getCpuConfigData(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                     const std::string& cpuId, const std::string& objPath,
                     const std::string& interface,
                     const nlohmann::json::json_pointer& jsonPtr,
                     const dbus::utility::ManagedObjectType& managedObjects)
{
    BMCWEB_LOG_INFO << "Getting CPU operating configs for " << cpuId;

    nlohmann::json& json = aResp->res.jsonValue;

    const sdbusplus::message::object_path* appliedConfig = nullptr;
    const bool* baseSpeedPriorityEnabled = nullptr;
    const BaseSpeedPrioritySettingsProperty* baseSpeedList = nullptr;

    dbus::utility::DBusPropertiesMap properties;
    dbus_utils::getPropertiesFromManagedObjects(managedObjects, objPath,
                                                interface, properties);

    const bool success = sdbusplus::unpackPropertiesNoThrow(
        dbus_utils::UnpackErrorPrinter(), properties, "AppliedConfig",
        appliedConfig, "BaseSpeedPriorityEnabled", baseSpeedPriorityEnabled);

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

    if (appliedConfig != nullptr)
    {
        const std::string& dbusPath = appliedConfig->str;
        std::string uri = "/redfish/v1/Systems/system/Processors/" + cpuId +
                          "/OperatingConfigs";
        nlohmann::json::object_t operatingConfig;
        operatingConfig["@odata.id"] = uri;
        json[jsonPtr]["OperatingConfigs"] = std::move(operatingConfig);

        // Reuse the D-Bus config object name for the Redfish
        // URI
        size_t baseNamePos = dbusPath.rfind('/');
        if (baseNamePos == std::string::npos ||
            baseNamePos == (dbusPath.size() - 1))
        {
            // If the AppliedConfig was somehow not a valid path,
            // skip adding any more properties, since everything
            // else is tied to this applied config.
            messages::internalError(aResp->res);
            return;
        }
        uri += '/';
        uri += dbusPath.substr(baseNamePos + 1);
        nlohmann::json::object_t appliedOperatingConfig;
        appliedOperatingConfig["@odata.id"] = uri;
        json[jsonPtr]["AppliedOperatingConfig"] =
            std::move(appliedOperatingConfig);

        // Once we found the current applied config, read the base freq core ids
        // out of Operating config.

        dbus::utility::DBusPropertiesMap config;
        dbus_utils::getPropertiesFromManagedObjects(
            managedObjects, dbusPath,
            "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig", config);

        const bool parseConfigSuccess = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), config,
            "BaseSpeedPrioritySettings", baseSpeedList);

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

        if (baseSpeedList != nullptr)
        {
            highSpeedCoreIdsHandler(aResp, jsonPtr, *baseSpeedList);
        }
    }

    if (baseSpeedPriorityEnabled != nullptr)
    {
        json[jsonPtr]["BaseSpeedPriorityState"] =
            *baseSpeedPriorityEnabled ? "Enabled" : "Disabled";
    }
}

/**
 * Populate the unique identifier in a Processor resource by requesting data
 * from the given D-Bus object.
 *
 * @param[in,out]   aResp           Async HTTP response.
 * @param[in]       objPath         D-Bus object to query.
 * @param[in]       interface       D-Bus interface to query.
 * @param[in]       jsonPtr         json pointer to index the response fields
 * @param[in]       managedObjects  Dbus objects with interfaces and properties.
 */
inline void
    getCpuUniqueId(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                   const std::string& objectPath, const std::string& interface,
                   const nlohmann::json::json_pointer& jsonPtr,
                   const dbus::utility::ManagedObjectType& managedObjects)
{
    BMCWEB_LOG_DEBUG << "Get CPU UniqueIdentifier";
    dbus::utility::DBusPropertiesMap properties;
    dbus_utils::getPropertiesFromManagedObjects(managedObjects, objectPath,
                                                interface, properties);

    const std::string* id = nullptr;

    const bool success = sdbusplus::unpackPropertiesNoThrow(
        dbus_utils::UnpackErrorPrinter(), properties, "UniqueIdentifier", id);

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

    if (id != nullptr)
    {
        aResp->res.jsonValue[jsonPtr]["ProcessorId"]
                            ["ProtectedIdentificationNumber"] = *id;
    }
}

inline void getCpuChassisAssociation(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& processorId, const std::string& objectPath,
    const nlohmann::json::json_pointer& jsonPtr)
{
    BMCWEB_LOG_DEBUG << "Get CPU -- Chassis association";

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    dbus_utils::getProperty<std::vector<std::string>>(
        "xyz.openbmc_project.ObjectMapper", objectPath + "/chassis",
        "xyz.openbmc_project.Association", "endpoints", requestContext,
        [asyncResp{asyncResp}, jsonPtr,
         processorId](const boost::system::error_code ec,
                      const std::vector<std::string>& chassisList) {
        if (ec)
        {
            return;
        }
        if (chassisList.empty())
        {
            return;
        }
        if (chassisList.size() > 1)
        {
            BMCWEB_LOG_DEBUG << processorId
                             << " is associated with mutliple chassis";
            return;
        }

        sdbusplus::message::object_path chassisPath(chassisList[0]);
        std::string chassisName = chassisPath.filename();
        if (chassisName.empty())
        {
            BMCWEB_LOG_ERROR << "filename() is empty in " << chassisPath.str;
            return;
        }
        asyncResp->res.jsonValue[jsonPtr]["Links"]["Chassis"] = {
            {"@odata.id", "/redfish/v1/Chassis/" + chassisName}};
    });
}

/**
 * @brief Fill out the links to associated memory of a processor
 * by looking up its D-Bus association.
 *
 * @param[in,out]   aResp       Async HTTP response.
 * @param[in]       objPath     D-Bus object to query.
 */
inline void getMemoryLinks(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                           const std::string& objectPath,
                           const nlohmann::json::json_pointer& jsonPtr)
{
    BMCWEB_LOG_DEBUG << "Get Processor -- Memory association";

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    dbus_utils::getProperty<std::vector<std::string>>(
        "xyz.openbmc_project.ObjectMapper", objectPath + "/memory",
        "xyz.openbmc_project.Association", "endpoints", requestContext,
        [asyncResp, jsonPtr](const boost::system::error_code ec,
                             const std::vector<std::string>& memoryList) {
        if (ec)
        {
            return;
        }
        if (memoryList.empty())
        {
            return;
        }
        nlohmann::json::array_t memoryLinks;
        for (const std::string& memory : memoryList)
        {
            sdbusplus::message::object_path memoryPath(memory);
            const std::string memoryName = memoryPath.filename();
            if (memoryName.empty())
            {
                BMCWEB_LOG_ERROR << "filename() is empty in " << memoryPath.str;
                return;
            }
            nlohmann::json::object_t memoryObject;
            memoryObject["@odata.id"] =
                "/redfish/v1/Systems/system/Memory/" + memoryName;
            memoryLinks.emplace_back(memoryObject);
        }
        asyncResp->res.jsonValue[jsonPtr]["Links"]["Memory"] =
            std::move(memoryLinks);
    });
}

/**
 * Find the D-Bus object representing the requested Processor, and call the
 * handler with the results. If matching object is not found, add 404 error to
 * response and don't call the handler.
 *
 * @param[in,out]   resp            Async HTTP response.
 * @param[in]       processorId     Redfish Processor Id.
 * @param[in]       handler         Callback to continue processing request upon
 *                                  successfully finding object.
 */
template <typename Handler>
inline void getProcessorObject(const std::shared_ptr<bmcweb::AsyncResp>& resp,
                               const std::string& processorId,
                               const std::string& systemPath, Handler&& handler)
{
    BMCWEB_LOG_DEBUG << "Get available system processor resources.";

    const bool multiHost = !systemPath.empty();

    // Default systemName is system and change if system is multi-host
    std::string systemName = "system";
    // The subtree to query for Dimms changes if single or multi-host
    std::string subtreeRoot = "/xyz/openbmc_project/inventory";

    if (multiHost)
    {
        systemName = sdbusplus::message::object_path(systemPath).filename();
        subtreeRoot = systemPath;
    }

    managedStore::ManagedObjectStoreContext context(resp);
    managedStore::GetManagedObjectStore()->getSubTree(
        subtreeRoot, 0, processorInterfaces, context,
        [resp{resp}, processorId, multiHost, systemPath,
         handler = std::forward<Handler>(handler), context](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreeResponse& subtree) mutable {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBUS response error: " << ec.value();
            messages::internalError(resp->res);
            return;
        }

        std::vector<std::string> serviceNames =
            dbus_utils::getServiceNamesFromSubtree(subtree);
        if (serviceNames.empty())
        {
            BMCWEB_LOG_ERROR << "Service list is empty";
            messages::internalError(resp->res);
            return;
        }

        sdbusplus::message::object_path path("/xyz/openbmc_project/inventory");
        dbus_utils::getManagedObjectsInEachService(
            std::move(serviceNames), path, context,
            [resp{std::move(resp)}, subtree, processorId, multiHost, systemPath,
             handler = std::forward<Handler>(handler)](
                const ManagedObjectByServiceMap& managedObjectsByService) {
            if (managedObjectsByService.empty())
            {
                BMCWEB_LOG_ERROR
                    << "GetManagedObjects does not return any object.";
                messages::internalError(resp->res);
                return;
            }
            BMCWEB_LOG_DEBUG << "Looping through subtree";

            for (const auto& [objectPath, serviceMap] : subtree)
            {
                BMCWEB_LOG_DEBUG << objectPath;
                if (multiHost && !objectPath.starts_with(systemPath))
                {
                    continue;
                }

                // Ignore any objects which don't end with our desired cpu name
                if (!objectPath.ends_with(processorId))
                {
                    continue;
                }

                // Filter out objects that don't have the CPU-specific
                // interfaces to make sure we can return 404 on non-CPUs
                // (e.g. /redfish/../Processors/dimm0)
                if (!dbus_utils::findInterfacesInServiceMap(
                        serviceMap, processorInterfaces))
                {
                    continue;
                }
                handler(objectPath, subtree, managedObjectsByService);
                return;
            }
            messages::resourceNotFound(resp->res, "Processor", processorId);
        });
    });
}

inline void
    getProcessorState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                      const std::string& service, const std::string& objPath,
                      const nlohmann::json::json_pointer& jsonPtr)
{

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    dbus_utils::getProperty<bool>(
        service, objPath, "xyz.openbmc_project.Inventory.Item", "Present",
        requestContext,
        [asyncResp, objPath, jsonPtr](const boost::system::error_code& ec,
                                      bool present) {
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "get presence failed for Processor State "
                             << objPath << " with error " << ec;

            if (ec.value() != EBADR)
            {
                messages::internalError(asyncResp->res);
            }
            return;
        }
        asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] =
            present ? "Enabled" : "Absent";
    });
}

inline void getProcessorStateData(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& processorId,
    const std::string& procStateId, const nlohmann::json::json_pointer& jsonPtr)
{
    BMCWEB_LOG_DEBUG << "Processor State Id: " << procStateId;
    asyncResp->res.jsonValue[jsonPtr]["@odata.id"] =
        crow::utility::urlFromPieces("redfish", "v1", "Systems", systemName,
                                     "Processors", processorId, "Oem", "Google",
                                     "ProcessorStates", procStateId);
    asyncResp->res.jsonValue[jsonPtr]["@odata.type"] =
        "#GoogleProcessorState.GoogleProcessorState";
    asyncResp->res.jsonValue[jsonPtr]["Id"] = procStateId;
    asyncResp->res.jsonValue[jsonPtr]["Name"] = "Processor";
    getProcessorState(asyncResp, "xyz.openbmc_project.EntityManager",
                      absl::StrCat("/xyz/openbmc_project/inventory/",
                                   systemName, "/processorstate/", procStateId),
                      jsonPtr);
}

void handleGetProcessorState(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& processorId,
    const std::string& procStateId)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    getProcessorStateData(asyncResp, systemName, processorId, procStateId,
                          ""_json_pointer);
}

using Mapper = dbus::utility::MapperGetSubTreePathsResponse;
inline void getProcessorStateLinksOrExpand(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& processorId, const nlohmann::json::json_pointer& jsonPtr,
    const std::string& systemName, uint8_t expandLevel,
    const boost::system::error_code& ec, const Mapper& procStatePaths)
{
    BMCWEB_LOG_DEBUG << "Get Processor State URL";

    if (ec)
    {
        BMCWEB_LOG_ERROR
            << "ProcessorState Collection GetSubTreePaths handler Dbus error "
            << ec;
        return;
    }
    nlohmann::json::array_t procStateLinks;
    size_t stateCount = 0;
    for (const std::string& procState : procStatePaths)
    {
        std::string procStateId =
            sdbusplus::message::object_path(procState).filename();
        nlohmann::json::json_pointer processorStatePtr =
            jsonPtr / "Oem" / "Google" / "ProcessorStates" / stateCount++;
        if (expandLevel > 0)
        {
            getProcessorStateData(aResp, systemName, processorId, procStateId,
                                  processorStatePtr);
        }
        else
        {
            nlohmann::json::object_t procStateObj;
            aResp->res.jsonValue[processorStatePtr]["@odata.id"] =
                crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                             systemName, "Processors",
                                             processorId, "Oem", "Google",
                                             "ProcessorStates", procStateId);
        }
    }
}

inline void
    getProcessorData(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                     const nlohmann::json::json_pointer& jsonPtr,
                     uint8_t expandLevel, const std::string& processorId,
                     const std::string& systemPath,
                     const std::string& objectPath,
                     const dbus::utility::MapperGetSubTreeResponse& subtree,
                     const ManagedObjectByServiceMap& managedObjectsMap)
{
    BMCWEB_LOG_DEBUG << "Get processor data.";

    const bool multiHost = !systemPath.empty();

    // Default systemName is system and change if system is multi-host
    std::string systemName = "system";

    if (multiHost)
    {
        systemName = sdbusplus::message::object_path(systemPath).filename();
    }

    aResp->res.addHeader(
        boost::beast::http::field::link,
        "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby");
    aResp->res.jsonValue[jsonPtr]["@odata.type"] =
        "#Processor.v1_11_0.Processor";
    aResp->res.jsonValue[jsonPtr]["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Systems", systemName, "Processors", processorId);

    // Get service to interface map for cpu
    dbus::utility::MapperServiceMap serviceMap;
    for (const auto& [parsedObjectPath, parsedServiceMap] : subtree)
    {
        if (objectPath == parsedObjectPath)
        {
            serviceMap = parsedServiceMap;
            break;
        }
    }

    for (const auto& [serviceName, interfaceList] : serviceMap)
    {
        auto iter = managedObjectsMap.find(serviceName);
        if (iter == managedObjectsMap.end())
        {
            BMCWEB_LOG_DEBUG << "Cpu data not available for serviceName "
                             << serviceName;
            continue;
        }

        BMCWEB_LOG_DEBUG << "Populate processor data from dbus interfaces.";
        for (const auto& interface : interfaceList)
        {
            if (interface == "xyz.openbmc_project.Inventory.Decorator.Asset")
            {
                getCpuAssetData(aResp, objectPath, interface, jsonPtr,
                                iter->second);
            }
            else if (interface ==
                     "xyz.openbmc_project.Inventory.Decorator.Revision")
            {
                getCpuRevisionData(aResp, objectPath, interface, jsonPtr,
                                   iter->second);
            }
            else if (interface == "xyz.openbmc_project.Inventory.Item.Cpu")
            {
                getCpuData(aResp, processorId, objectPath, interface, jsonPtr,
                           iter->second);
            }
            else if (interface ==
                     "xyz.openbmc_project.Inventory.Item.Accelerator")
            {
                getAcceleratorData(aResp, processorId, objectPath, interface,
                                   jsonPtr, iter->second);
            }
            else if (
                interface ==
                "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig")
            {
                getCpuConfigData(aResp, processorId, objectPath, interface,
                                 jsonPtr, iter->second);
            }
            else if (interface ==
                     "xyz.openbmc_project.Inventory.Decorator.LocationCode")
            {
                location_util::getLocationCodeFromManagedObject(
                    aResp, objectPath, interface, jsonPtr / "Location",
                    iter->second);
                location_util::getPartLocationContext(
                    aResp, jsonPtr / "Location", objectPath + "/chassis");
            }
            else if (interface == "xyz.openbmc_project.Common.UUID")
            {
                getProcessorUUID(aResp, objectPath, interface, jsonPtr,
                                 iter->second);
            }
            else if (interface ==
                     "xyz.openbmc_project.Inventory.Decorator.UniqueIdentifier")
            {
                getCpuUniqueId(aResp, objectPath, interface, jsonPtr,
                               iter->second);
            }
            else
            {
                std::optional<std::string> locationType =
                    location_util::getLocationType(interface);
                if (locationType == std::nullopt)
                {
                    BMCWEB_LOG_DEBUG
                        << "getLocationType for Processor failed for "
                        << interface;
                    continue;
                }

                aResp->res.jsonValue[jsonPtr]["Location"]["PartLocation"]
                                    ["LocationType"] = *locationType;
            }
        }
    }
    getCpuChassisAssociation(aResp, processorId, objectPath, jsonPtr);
    getMemoryLinks(aResp, objectPath, jsonPtr);

    managedStore::ManagedObjectStoreContext context(aResp);
    constexpr std::array<std::string_view, 1> procStateIntf = {
        "xyz.openbmc_project.Inventory.Item.ProcessorState"};
    dbus_utils::getSubTreePaths(
        "/xyz/openbmc_project/inventory", 0, procStateIntf, context,
        std::bind_front(getProcessorStateLinksOrExpand, aResp, processorId,
                        jsonPtr, systemName, expandLevel));

    // TODO(edward): Support SubProcessors and ProcessorMetrics for Multi-Host
    // as use-cases arise
    if (!multiHost)
    {
        if (expandLevel > 0)
        {
            nlohmann::json::json_pointer subProcessorPtr =
                jsonPtr / "SubProcessors";
            getSubProcessorCoreCollectionWithExpand(
                aResp, subProcessorPtr, expandLevel - 1, processorId,
                objectPath, subtree, managedObjectsMap);
        }
        else
        {
            aResp->res.jsonValue[jsonPtr]["SubProcessors"]["@odata.id"] =
                crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                             "system", "Processors",
                                             processorId, "SubProcessors");
        }

        if (expandLevel > 0)
        {
            nlohmann::json::json_pointer metricsPtr = jsonPtr / "Metrics";
            handleGetCpuMetrics(aResp, metricsPtr, processorId);
        }
        else
        {
            // Inserting the "Metrics" JSON stanza
            std::string metricsUrl = aResp->res.jsonValue[jsonPtr]["@odata.id"];
            metricsUrl += "/ProcessorMetrics";
            nlohmann::json::object_t metricsObj;
            metricsObj["@odata.id"] = std::move(metricsUrl);
            aResp->res.jsonValue[jsonPtr]["Metrics"] = std::move(metricsObj);
        }
    }
}

template <typename Handler>
inline void getProcessorPaths(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                              const std::string& processorId, Handler&& handler)
{
    std::array<std::string_view, 1> interfaces{
        "xyz.openbmc_project.Inventory.Item.Cpu"};

    managedStore::ManagedObjectStoreContext requestContext(aResp);
    managedStore::GetManagedObjectStore()->getSubTreePaths(
        "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
        [processorId, aResp{aResp},
         handler{std::forward<Handler>(handler)}](
            const boost::system::error_code ec,
            const std::vector<std::string>& subTreePaths) {
        if (ec)
        {
            handler(ec, "");
            return;
        }

        for (const std::string& cpuPath : subTreePaths)
        {
            if (sdbusplus::message::object_path(cpuPath).filename() !=
                processorId)
            {
                continue;
            }

            handler(ec, cpuPath);
            return;
        }

        // Set an error code since valid cpu path is not found
        handler(boost::system::errc::make_error_code(
                    boost::system::errc::no_such_file_or_directory),
                "");
    });
}

template <typename Handler>
inline void
    getSubProcessorCorePaths(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                             const std::string& processorId,
                             const std::string& coreId, Handler&& handler)
{

    std::array<std::string_view, 1> interfaces{
        "xyz.openbmc_project.Inventory.Item.Cpu"};
    managedStore::ManagedObjectStoreContext requestContext(aResp);
    managedStore::GetManagedObjectStore()->getSubTreePaths(
        "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
        [processorId, coreId, aResp{aResp},
         handler{std::forward<Handler>(handler)},
         requestContext](const boost::system::error_code ec,
                         const std::vector<std::string>& subTreeCpuPaths) {
        if (ec)
        {
            handler(ec, "");
            return;
        }

        for (const std::string& cpuPath : subTreeCpuPaths)
        {
            if (sdbusplus::message::object_path(cpuPath).filename() !=
                processorId)
            {
                continue;
            }

            std::array<std::string_view, 1> interfaces{
                "xyz.openbmc_project.Inventory.Item.CpuCore"};
            managedStore::GetManagedObjectStore()->getSubTreePaths(
                "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
                [processorId, coreId, aResp{aResp},
                 handler](const boost::system::error_code ec2,
                          const std::vector<std::string>& subTreeCorePaths) {
                if (ec2)
                {
                    handler(ec2, "");
                    return;
                }

                for (const std::string& corePath : subTreeCorePaths)
                {
                    if (sdbusplus::message::object_path(corePath).filename() !=
                        coreId)
                    {
                        continue;
                    }
                    handler(ec2, corePath);
                    return;
                }
                // Set an error code since valid processor core path is not
                // found
                handler(boost::system::errc::make_error_code(
                            boost::system::errc::no_such_file_or_directory),
                        "");
            });
            return;
        }

        // Set an error code since valid processor cpu path is not found
        handler(boost::system::errc::make_error_code(
                    boost::system::errc::no_such_file_or_directory),
                "");
    });
}

inline void
    getCoreThreadData(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                      const nlohmann::json::json_pointer& jsonPtr,
                      [[maybe_unused]] const uint8_t expandLevel,
                      const std::string& processorId, const std::string& coreId,
                      const std::string& threadId,
                      const std::string& threadPath,
                      const dbus::utility::MapperGetSubTreeResponse& subtree,
                      const ManagedObjectByServiceMap& managedObjectsMap)
{
    aResp->res.jsonValue[jsonPtr]["@odata.type"] =
        "#Processor.v1_11_0.Processor";
    aResp->res.jsonValue[jsonPtr]["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Systems", "system", "Processors", processorId,
        "SubProcessors", coreId, "SubProcessors", threadId);
    aResp->res.jsonValue[jsonPtr]["Name"] = "SubProcessor";
    aResp->res.jsonValue[jsonPtr]["ProcessorType"] = "Thread";
    aResp->res.jsonValue[jsonPtr]["Id"] = threadId;

    aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled";
    aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";

    bool present = false;
    bool functional = false;

    dbus::utility::MapperServiceMap serviceMap;
    for (const auto& [parsedObjectPath, parsedServiceMap] : subtree)
    {
        if (threadPath == parsedObjectPath)
        {
            serviceMap = parsedServiceMap;
            break;
        }
    }

    for (const auto& [serviceName, interfaceList] : serviceMap)
    {
        auto iter = managedObjectsMap.find(serviceName);
        if (iter == managedObjectsMap.end())
        {
            BMCWEB_LOG_DEBUG << "Thread data not available for serviceName "
                             << serviceName;
            continue;
        }

        for (const auto& interface : interfaceList)
        {
            dbus::utility::DBusPropertiesMap properties;
            if (interface == "xyz.openbmc_project.State."
                             "Decorator.OperationalStatus")
            {
                const bool* propertyFunctional = nullptr;
                dbus_utils::getPropertiesFromManagedObjects(
                    iter->second, threadPath, interface, properties);
                const bool success = sdbusplus::unpackPropertiesNoThrow(
                    dbus_utils::UnpackErrorPrinter(), properties, "Functional",
                    propertyFunctional);
                if (!success || propertyFunctional == nullptr)
                {
                    continue;
                }
                functional = *propertyFunctional;
            }
            else if (interface == "xyz.openbmc_project.Inventory.Item")
            {
                const bool* propertyPresent = nullptr;
                const std::string* propertyPrettyName = nullptr;
                dbus_utils::getPropertiesFromManagedObjects(
                    iter->second, threadPath, interface, properties);
                const bool success = sdbusplus::unpackPropertiesNoThrow(
                    dbus_utils::UnpackErrorPrinter(), properties, "Present",
                    propertyPresent, "PrettyName", propertyPrettyName);
                if (!success)
                {
                    continue;
                }

                if (propertyPresent != nullptr)
                {
                    present = *propertyPresent;
                }

                if (propertyPrettyName != nullptr)
                {
                    aResp->res.jsonValue[jsonPtr]["Name"] = *propertyPrettyName;
                }
            }
            else if (interface ==
                     "xyz.openbmc_project.Inventory.Item.CpuThread")
            {
                const uint32_t* propertyMicrocode = nullptr;
                dbus_utils::getPropertiesFromManagedObjects(
                    iter->second, threadPath, interface, properties);
                const bool success = sdbusplus::unpackPropertiesNoThrow(
                    dbus_utils::UnpackErrorPrinter(), properties, "Microcode",
                    propertyMicrocode);
                if (!success)
                {
                    continue;
                }

                if (propertyMicrocode != nullptr)
                {
                    aResp->res
                        .jsonValue[jsonPtr]["ProcessorId"]["MicrocodeInfo"] =
                        "0x" + intToHexString(*propertyMicrocode, 8);
                }
            }
        }
    }

    if (!present)
    {
        aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
    }

    if (!functional)
    {
        aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "Critical";
    }

    if (expandLevel > 0)
    {
        nlohmann::json::json_pointer metricsPtr = jsonPtr / "Metrics";
        handleGetCpuCoreThreadMetrics(aResp, metricsPtr, processorId, coreId,
                                      threadId);
    }
    else
    {
        // Inserting the "Metrics" JSON stanza
        std::string metricsUrl = aResp->res.jsonValue[jsonPtr]["@odata.id"];
        metricsUrl += "/ProcessorMetrics";
        nlohmann::json::object_t metricsObj;
        metricsObj["@odata.id"] = std::move(metricsUrl);
        aResp->res.jsonValue[jsonPtr]["Metrics"] = std::move(metricsObj);
    }
}

inline void getSubProcessorThreadData(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& processorId, const std::string& coreId,
    const std::string& threadId, const boost::system::error_code ec,
    const std::string& corePath)
{
    if (ec)
    {
        BMCWEB_LOG_DEBUG << "DBUS response error, ec: " << ec.value();
        // No sub processor thread objects found by mapper
        if (ec.value() == boost::system::errc::io_error)
        {
            messages::resourceNotFound(aResp->res,
                                       "#Processor.v1_11_0.Processor", coreId);
            return;
        }

        messages::internalError(aResp->res);
        return;
    }
    aResp->res.addHeader(
        boost::beast::http::field::link,
        "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby");

    managedStore::ManagedObjectStoreContext context(aResp);
    managedStore::GetManagedObjectStore()->getSubTree(
        corePath, 0, subProcessorThreadInterfaces, context,
        [aResp{aResp}, processorId, coreId, threadId,
         context](const boost::system::error_code& ec2,
                  const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec2)
        {
            BMCWEB_LOG_DEBUG << "DBUS response error, ec2: " << ec2.value();
            // No sub processor core objects found by mapper
            if (ec2.value() == boost::system::errc::io_error)
            {
                messages::resourceNotFound(
                    aResp->res, "#Processor.v1_11_0.Processor", coreId);
                return;
            }

            messages::internalError(aResp->res);
            return;
        }

        std::vector<std::string> serviceNames =
            dbus_utils::getServiceNamesFromSubtree(subtree);

        sdbusplus::message::object_path path("/xyz/openbmc_project/inventory");
        dbus_utils::getManagedObjectsInEachService(
            std::move(serviceNames), path, context,
            [aResp{aResp}, subtree, processorId, coreId, threadId](
                const ManagedObjectByServiceMap& managedObjectsByService) {
            if (managedObjectsByService.empty())
            {
                messages::internalError(aResp->res);
                return;
            }

            for (const auto& [objectPath, serviceMap] : subtree)
            {
                if (sdbusplus::message::object_path(objectPath).filename() !=
                    threadId)
                {
                    continue;
                }

                getCoreThreadData(aResp, ""_json_pointer, 0, processorId,
                                  coreId, threadId, objectPath, subtree,
                                  managedObjectsByService);
                return;
            }

            // Object not found
            messages::resourceNotFound(
                aResp->res, "#Processor.v1_11_0.Processor", threadId);
        });
    });
}

inline void getSubProcessorThreadMembers(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& processorId, const std::string& coreId,
    const boost::system::error_code ec, const std::string& corePath)
{
    if (ec)
    {
        BMCWEB_LOG_DEBUG << "DBUS response error, ec: " << ec.value();
        // No sub processor core objects found by mapper
        if (ec.value() == boost::system::errc::io_error)
        {
            messages::resourceNotFound(aResp->res,
                                       "#Processor.v1_11_0.Processor", coreId);
            return;
        }

        messages::internalError(aResp->res);
        return;
    }

    aResp->res.addHeader(
        boost::beast::http::field::link,
        "</redfish/v1/JsonSchemas/ProcessorCollection/ProcessorCollection.json>; rel=describedby");
    aResp->res.jsonValue["@odata.type"] =
        "#ProcessorCollection.ProcessorCollection";
    aResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Systems", "system", "Processors", processorId,
        "SubProcessors", coreId, "SubProcessors");
    aResp->res.jsonValue["Name"] = "SubProcessor Collection";

    const boost::urls::url& subProcessorsPath = crow::utility::urlFromPieces(
        "redfish", "v1", "Systems", "system", "Processors", processorId,
        "SubProcessors", coreId, "SubProcessors");

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

    collection_util::getCollectionMembers(aResp, subProcessorsPath, interfaces,
                                          corePath.c_str());
}

inline void
    getCpuCoreData(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                   const nlohmann::json::json_pointer& jsonPtr,
                   uint8_t expandLevel, const std::string& processorId,
                   const std::string& coreId, const std::string& corePath,
                   const dbus::utility::MapperGetSubTreeResponse& subtree,
                   const ManagedObjectByServiceMap& managedObjectsMap)
{
    aResp->res.jsonValue[jsonPtr]["@odata.type"] =
        "#Processor.v1_11_0.Processor";
    aResp->res.jsonValue[jsonPtr]["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Systems", "system", "Processors", processorId,
        "SubProcessors", coreId);

    aResp->res.jsonValue[jsonPtr]["Name"] = "SubProcessor";
    aResp->res.jsonValue[jsonPtr]["ProcessorType"] = "Core";
    aResp->res.jsonValue[jsonPtr]["Id"] = coreId;

    if (expandLevel > 0)
    {
        nlohmann::json::json_pointer subProcessorPtr =
            jsonPtr / "SubProcessors";
        getSubProcessorThreadCollectionWithExpand(
            aResp, subProcessorPtr, expandLevel - 1, processorId, coreId,
            corePath, subtree, managedObjectsMap);
    }
    else
    {
        aResp->res.jsonValue[jsonPtr]["SubProcessors"]["@odata.id"] =
            crow::utility::urlFromPieces(
                "redfish", "v1", "Systems", "system", "Processors", processorId,
                "SubProcessors", coreId, "SubProcessors");
    }

    aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled";
    aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";

    bool present = false;
    bool functional = false;

    dbus::utility::MapperServiceMap serviceMap;
    for (const auto& [parsedObjectPath, parsedServiceMap] : subtree)
    {
        if (corePath == parsedObjectPath)
        {
            serviceMap = parsedServiceMap;
            break;
        }
    }

    for (const auto& [serviceName, interfaceList] : serviceMap)
    {
        auto iter = managedObjectsMap.find(serviceName);
        if (iter == managedObjectsMap.end())
        {
            BMCWEB_LOG_DEBUG << "Cpu data not available for serviceName "
                             << serviceName;
            continue;
        }

        for (const auto& interface : interfaceList)
        {
            dbus::utility::DBusPropertiesMap properties;
            if (interface == "xyz.openbmc_project.State."
                             "Decorator.OperationalStatus")
            {
                const bool* propertyFunctional = nullptr;
                dbus_utils::getPropertiesFromManagedObjects(
                    iter->second, corePath, interface, properties);
                const bool success = sdbusplus::unpackPropertiesNoThrow(
                    dbus_utils::UnpackErrorPrinter(), properties, "Functional",
                    propertyFunctional);

                if (!success)
                {
                    continue;
                }

                if (propertyFunctional != nullptr)
                {
                    functional = *propertyFunctional;
                }
            }
            else if (interface == "xyz.openbmc_project.Inventory.Item")
            {
                const bool* propertyPresent = nullptr;
                const std::string* propertyPrettyName = nullptr;
                dbus_utils::getPropertiesFromManagedObjects(
                    iter->second, corePath, interface, properties);
                const bool success = sdbusplus::unpackPropertiesNoThrow(
                    dbus_utils::UnpackErrorPrinter(), properties, "Present",
                    propertyPresent, "PrettyName", propertyPrettyName);

                if (!success)
                {
                    continue;
                }

                if (propertyPresent != nullptr)
                {
                    present = *propertyPresent;
                }

                if (propertyPrettyName != nullptr)
                {
                    aResp->res.jsonValue[jsonPtr]["Name"] = *propertyPrettyName;
                }
            }
            else if (interface == "xyz.openbmc_project.Inventory.Item.CpuCore")
            {
                const uint32_t* propertyMicrocode = nullptr;
                dbus_utils::getPropertiesFromManagedObjects(
                    iter->second, corePath, interface, properties);
                const bool success = sdbusplus::unpackPropertiesNoThrow(
                    dbus_utils::UnpackErrorPrinter(), properties, "Microcode",
                    propertyMicrocode);
                if (!success)
                {
                    continue;
                }

                if (propertyMicrocode != nullptr)
                {
                    aResp->res
                        .jsonValue[jsonPtr]["ProcessorId"]["MicrocodeInfo"] =
                        "0x" + intToHexString(*propertyMicrocode, 8);
                }
            }
        }
    }

    if (!present)
    {
        aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
    }

    if (!functional)
    {
        aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "Critical";
    }

    // The "Metrics" stanza is deliberately omitted at the Core layer
}

inline void getSubProcessorCoreData(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& processorId, const std::string& coreId,
    const boost::system::error_code ec, const std::string& cpuPath)
{
    if (ec)
    {
        BMCWEB_LOG_DEBUG << "DBUS response error, ec: " << ec.value();
        // No processor objects found by mapper
        if (ec.value() == boost::system::errc::io_error)
        {
            messages::resourceNotFound(
                aResp->res, "#Processor.v1_11_0.Processor", processorId);
            return;
        }

        messages::internalError(aResp->res);
        return;
    }
    aResp->res.addHeader(
        boost::beast::http::field::link,
        "</redfish/v1/JsonSchemas/Processor/Processor.json>; rel=describedby");

    std::array<std::string_view, 1> interfaces{
        "xyz.openbmc_project.Inventory.Item.CpuCore"};
    managedStore::ManagedObjectStoreContext context(aResp);
    managedStore::GetManagedObjectStore()->getSubTree(
        cpuPath, 0, interfaces, context,
        [aResp{aResp}, processorId, coreId,
         context](const boost::system::error_code& ec2,
                  const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec2)
        {
            BMCWEB_LOG_DEBUG << "DBUS response error, ec2: " << ec2.value();
            // No processor objects found by mapper
            if (ec2.value() == boost::system::errc::io_error)
            {
                messages::resourceNotFound(
                    aResp->res, "#Processor.v1_11_0.Processor", processorId);
                return;
            }

            messages::internalError(aResp->res);
            return;
        }

        std::vector<std::string> serviceNames =
            dbus_utils::getServiceNamesFromSubtree(subtree);

        sdbusplus::message::object_path path("/xyz/openbmc_project/inventory");
        dbus_utils::getManagedObjectsInEachService(
            std::move(serviceNames), path, context,
            [aResp{aResp}, subtree, processorId,
             coreId](const ManagedObjectByServiceMap& managedObjectsByService) {
            if (managedObjectsByService.empty())
            {
                messages::internalError(aResp->res);
                return;
            }

            for (const auto& [objectPath, serviceMap] : subtree)
            {
                if (sdbusplus::message::object_path(objectPath).filename() !=
                    coreId)
                {
                    continue;
                }
                getCpuCoreData(aResp, ""_json_pointer, 0, processorId, coreId,
                               objectPath, subtree, managedObjectsByService);
                return;
            }

            // Object not found
            messages::resourceNotFound(aResp->res,
                                       "#Processor.v1_11_0.Processor", coreId);
        });
    });
}

inline void
    getSubProcessorCoreMembers(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                               const std::string& processorId,
                               const boost::system::error_code ec,
                               const std::string& cpuPath)
{
    if (ec)
    {
        BMCWEB_LOG_DEBUG << "DBUS response error, ec: " << ec.value();
        // No processor objects found by mapper
        if (ec.value() == boost::system::errc::io_error)
        {
            messages::resourceNotFound(
                aResp->res, "#Processor.v1_11_0.Processor", processorId);
            return;
        }

        messages::internalError(aResp->res);
        return;
    }

    aResp->res.addHeader(
        boost::beast::http::field::link,
        "</redfish/v1/JsonSchemas/ProcessorCollection/ProcessorCollection.json>; rel=describedby");
    aResp->res.jsonValue["@odata.type"] =
        "#ProcessorCollection.ProcessorCollection";
    aResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Systems", "system", "Processors", processorId,
        "SubProcessors");
    aResp->res.jsonValue["Name"] = "SubProcessor Collection";

    const boost::urls::url& subProcessorsPath = crow::utility::urlFromPieces(
        "redfish", "v1", "Systems", "system", "Processors", processorId,
        "SubProcessors");

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

    collection_util::getCollectionMembers(aResp, subProcessorsPath, interfaces,
                                          cpuPath.c_str());
}

inline void getSubProcessorThreadCollectionWithExpand(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const nlohmann::json::json_pointer& jsonPtr, uint8_t expandLevel,
    const std::string& processorId, const std::string& coreId,
    const std::string& corePath,
    const dbus::utility::MapperGetSubTreeResponse& subtree,
    const ManagedObjectByServiceMap& managedObjectsMap)
{
    aResp->res.jsonValue[jsonPtr]["Name"] = "SubProcessor Collection";
    aResp->res.jsonValue[jsonPtr]["@odata.type"] =
        "#ProcessorCollection.ProcessorCollection";
    aResp->res.jsonValue[jsonPtr]["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Systems", "system", "Processors", processorId,
        "SubProcessors", coreId, "SubProcessors");

    // Maps thread ID to threadObjectPath
    std::map<std::string, std::string, AlphanumLess<std::string>>
        threadIdToObjectPath;

    for (const auto& [objectPath, serviceMap] : subtree)
    {
        if (!objectPath.starts_with(corePath) ||
            !dbus_utils::findInterfacesInServiceMap(
                serviceMap, subProcessorThreadInterfaces))
        {
            continue;
        }
        sdbusplus::message::object_path threadPath(objectPath);
        const std::string& threadId = threadPath.filename();
        threadIdToObjectPath.insert({threadId, threadPath});
    }

    BMCWEB_LOG_DEBUG << "Core path: " << corePath
                     << " thread count: " << threadIdToObjectPath.size();

    if (threadIdToObjectPath.empty())
    {
        BMCWEB_LOG_WARNING << "D-Bus CPU thread count was somehow empty";
        aResp->res.jsonValue[jsonPtr]["Members@odata.count"] = 0;
        aResp->res.jsonValue[jsonPtr]["Members"] = nlohmann::json::array();
        return;
    }

    size_t threadMemberCount = 0;
    for (const auto& [threadId, _] : threadIdToObjectPath)
    {
        nlohmann::json::json_pointer threadMemberPtr =
            jsonPtr / "Members" / threadMemberCount;
        if (expandLevel > 0)
        {
            getCoreThreadData(aResp, threadMemberPtr, expandLevel - 1,
                              processorId, coreId, threadId,
                              threadIdToObjectPath[threadId], subtree,
                              managedObjectsMap);
        }
        else
        {
            aResp->res.jsonValue[threadMemberPtr]["@odata.id"] =
                crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                             "system", "Processors",
                                             processorId, "SubProcessors",
                                             coreId, "SubProcessors", threadId);
        }
        threadMemberCount++;
    }
    aResp->res.jsonValue[jsonPtr]["Members@odata.count"] = threadMemberCount;
}

inline void getSubProcessorCoreCollectionWithExpand(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const nlohmann::json::json_pointer& jsonPtr, uint8_t expandLevel,
    const std::string& processorId, const std::string& cpuPath,
    const dbus::utility::MapperGetSubTreeResponse& subtree,
    const ManagedObjectByServiceMap& managedObjectsMap)
{
    aResp->res.jsonValue[jsonPtr]["@odata.type"] =
        "#ProcessorCollection.ProcessorCollection";
    aResp->res.jsonValue[jsonPtr]["Name"] = "SubProcessor Collection";
    aResp->res.jsonValue[jsonPtr]["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Systems", "system", "Processors", processorId,
        "SubProcessors");

    // Maps core ID to coreObjectPath
    std::map<std::string, std::string, AlphanumLess<std::string>>
        coreIdToObjectPath;

    for (const auto& [objectPath, serviceMap] : subtree)
    {
        if (!objectPath.starts_with(cpuPath) ||
            !dbus_utils::findInterfacesInServiceMap(serviceMap,
                                                    subProcessorCoreInterfaces))
        {
            continue;
        }
        sdbusplus::message::object_path corePath(objectPath);
        const std::string& coreId = corePath.filename();
        coreIdToObjectPath.insert({coreId, objectPath});
    }

    if (coreIdToObjectPath.empty())
    {
        BMCWEB_LOG_WARNING << "D-Bus CPU core count was somehow empty";
        aResp->res.jsonValue[jsonPtr]["Members@odata.count"] = 0;
        aResp->res.jsonValue[jsonPtr]["Members"] = nlohmann::json::array();
        return;
    }

    size_t coreMemberCount = 0;
    for (const auto& [coreId, _] : coreIdToObjectPath)
    {
        nlohmann::json::json_pointer coreMemberPtr =
            jsonPtr / "Members" / coreMemberCount;
        if (expandLevel > 0)
        {
            getCpuCoreData(aResp, coreMemberPtr, expandLevel - 1, processorId,
                           coreId, coreIdToObjectPath[coreId], subtree,
                           managedObjectsMap);
        }
        else
        {
            aResp->res.jsonValue[coreMemberPtr]["@odata.id"] =
                crow::utility::urlFromPieces(
                    "redfish", "v1", "Systems", "system", "Processors",
                    processorId, "SubProcessors", coreId);
        }
        coreMemberCount++;
    }

    aResp->res.jsonValue[jsonPtr]["Members@odata.count"] = coreMemberCount;
}

inline void getProcessorCollectionWithExpand(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const dbus::utility::MapperGetSubTreeResponse& subtree,
    const ManagedObjectByServiceMap& managedObjectsMap, uint8_t expandLevel,
    const std::string& systemPath)
{
    BMCWEB_LOG_DEBUG << "Get processor collection with expand.";

    const bool multiHost = !systemPath.empty();

    // Maps cpu ID to cpuObjectPath.
    std::map<std::string, std::string, AlphanumLess<std::string>>
        cpuNameToObjectPath;

    for (const auto& [objectPath, serviceMap] : subtree)
    {

        if (!dbus_utils::findInterfacesInServiceMap(serviceMap,
                                                    processorInterfaces))
        {
            continue;
        }
        sdbusplus::message::object_path cpuPath(objectPath);

        // For multi-host systems, the object path of the cpu must be a
        // descendant of the systemPath. (e.g. if systemPath = /a/b, then
        // objectPath must be some pattern like /a/b/..)
        if (multiHost && !objectPath.starts_with(systemPath))
        {
            continue;
        }

        const std::string& cpuId = cpuPath.filename();
        cpuNameToObjectPath.insert({cpuId, cpuPath});
    }

    // If no cpus found, return
    if (cpuNameToObjectPath.empty())
    {
        BMCWEB_LOG_WARNING << "D-Bus CPU count was somehow empty";
        aResp->res.jsonValue["Members@odata.count"] = 0;
        aResp->res.jsonValue["Members"] = nlohmann::json::array();
        return;
    }

    size_t cpuMemberCount = 0;
    for (const auto& [cpu, _] : cpuNameToObjectPath)
    {
        nlohmann::json::json_pointer cpuMemberPtr =
            "/Members"_json_pointer / cpuMemberCount;
        getProcessorData(aResp, cpuMemberPtr, expandLevel - 1, cpu, systemPath,
                         cpuNameToObjectPath[cpu], subtree, managedObjectsMap);
        cpuMemberCount++;
    }

    aResp->res.jsonValue["Members@odata.count"] = cpuMemberCount;
    aResp->res.jsonValue["Name"] = "Processor Collection";
}

/**
 * Request all the properties for the given D-Bus object and fill out the
 * related entries in the Redfish OperatingConfig response.
 *
 * @param[in,out]   aResp       Async HTTP response.
 * @param[in]       service     D-Bus service name to query.
 * @param[in]       objPath     D-Bus object to query.
 */
inline void
    getOperatingConfigData(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                           const std::string& service,
                           const std::string& objPath)
{
    managedStore::ManagedObjectStoreContext context(aResp);
    managedStore::GetManagedObjectStore()->getAllProperties(
        service, objPath,
        "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig", context,
        [aResp](const boost::system::error_code& ec,
                const dbus::utility::DBusPropertiesMap& properties) {
        if (ec)
        {
            BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", " << ec.message();
            messages::internalError(aResp->res);
            return;
        }

        const size_t* availableCoreCount = nullptr;
        const uint32_t* baseSpeed = nullptr;
        const uint32_t* maxJunctionTemperature = nullptr;
        const uint32_t* maxSpeed = nullptr;
        const uint32_t* powerLimit = nullptr;
        const TurboProfileProperty* turboProfile = nullptr;
        const BaseSpeedPrioritySettingsProperty* baseSpeedPrioritySettings =
            nullptr;

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), properties, "AvailableCoreCount",
            availableCoreCount, "BaseSpeed", baseSpeed,
            "MaxJunctionTemperature", maxJunctionTemperature, "MaxSpeed",
            maxSpeed, "PowerLimit", powerLimit, "TurboProfile", turboProfile,
            "BaseSpeedPrioritySettings", baseSpeedPrioritySettings);

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

        nlohmann::json& json = aResp->res.jsonValue;

        if (availableCoreCount != nullptr)
        {
            json["TotalAvailableCoreCount"] = *availableCoreCount;
        }

        if (baseSpeed != nullptr)
        {
            json["BaseSpeedMHz"] = *baseSpeed;
        }

        if (maxJunctionTemperature != nullptr)
        {
            json["MaxJunctionTemperatureCelsius"] = *maxJunctionTemperature;
        }

        if (maxSpeed != nullptr)
        {
            json["MaxSpeedMHz"] = *maxSpeed;
        }

        if (powerLimit != nullptr)
        {
            json["TDPWatts"] = *powerLimit;
        }

        if (turboProfile != nullptr)
        {
            nlohmann::json& turboArray = json["TurboProfile"];
            turboArray = nlohmann::json::array();
            for (const auto& [turboSpeed, coreCount] : *turboProfile)
            {
                nlohmann::json::object_t turbo;
                turbo["ActiveCoreCount"] = coreCount;
                turbo["MaxSpeedMHz"] = turboSpeed;
                turboArray.emplace_back(std::move(turbo));
            }
        }

        if (baseSpeedPrioritySettings != nullptr)
        {
            nlohmann::json& baseSpeedArray = json["BaseSpeedPrioritySettings"];
            baseSpeedArray = nlohmann::json::array();
            for (const auto& [baseSpeedMhz, coreList] :
                 *baseSpeedPrioritySettings)
            {
                nlohmann::json::object_t speed;
                speed["CoreCount"] = coreList.size();
                speed["CoreIDs"] = coreList;
                speed["BaseSpeedMHz"] = baseSpeedMhz;
                baseSpeedArray.emplace_back(std::move(speed));
            }
        }
    });
}

/**
 * Handle the D-Bus response from attempting to set the CPU's AppliedConfig
 * property. Main task is to translate error messages into Redfish errors.
 *
 * @param[in,out]   resp    HTTP response.
 * @param[in]       setPropVal  Value which we attempted to set.
 * @param[in]       ec      D-Bus response error code.
 * @param[in]       msg     D-Bus response message.
 */
inline void
    handleAppliedConfigResponse(const std::shared_ptr<bmcweb::AsyncResp>& resp,
                                const std::string& setPropVal,
                                const boost::system::error_code& ec,
                                const sdbusplus::message_t& msg)
{
    if (!ec)
    {
        BMCWEB_LOG_DEBUG << "Set Property succeeded";
        return;
    }

    BMCWEB_LOG_DEBUG << "Set Property failed: " << ec;

    const sd_bus_error* dbusError = msg.get_error();
    if (dbusError == nullptr)
    {
        messages::internalError(resp->res);
        return;
    }

    // The asio error code doesn't know about our custom errors, so we have to
    // parse the error string. Some of these D-Bus -> Redfish translations are a
    // stretch, but it's good to try to communicate something vaguely useful.
    if (strcmp(dbusError->name,
               "xyz.openbmc_project.Common.Error.InvalidArgument") == 0)
    {
        // Service did not like the object_path we tried to set.
        messages::propertyValueIncorrect(
            resp->res, "AppliedOperatingConfig/@odata.id", setPropVal);
    }
    else if (strcmp(dbusError->name,
                    "xyz.openbmc_project.Common.Error.NotAllowed") == 0)
    {
        // Service indicates we can never change the config for this processor.
        messages::propertyNotWritable(resp->res, "AppliedOperatingConfig");
    }
    else if (strcmp(dbusError->name,
                    "xyz.openbmc_project.Common.Error.Unavailable") == 0)
    {
        // Service indicates the config cannot be changed right now, but maybe
        // in a different system state.
        messages::resourceInStandby(resp->res);
    }
    else
    {
        messages::internalError(resp->res);
    }
}

/**
 * Handle the PATCH operation of the AppliedOperatingConfig property. Do basic
 * validation of the input data, and then set the D-Bus property.
 *
 * @param[in,out]   resp            Async HTTP response.
 * @param[in]       processorId     Processor's Id.
 * @param[in]       appliedConfigUri    New property value to apply.
 * @param[in]       cpuObjectPath   Path of CPU object to modify.
 * @param[in]       serviceMap      Service map for CPU object.
 */
inline void patchAppliedOperatingConfig(
    const std::shared_ptr<bmcweb::AsyncResp>& resp,
    const std::string& processorId, const std::string& appliedConfigUri,
    const std::string& cpuObjectPath,
    const dbus::utility::MapperGetSubTreeResponse& subtree,
    [[maybe_unused]] const ManagedObjectByServiceMap& managedObjectsMap)
{
    // Get Service map for the object path.
    dbus::utility::MapperServiceMap serviceMap;
    for (const auto& [parsedObjectPath, parsedServiceMap] : subtree)
    {
        if (cpuObjectPath == parsedObjectPath)
        {
            serviceMap = parsedServiceMap;
            break;
        }
    }

    // Check that the property even exists by checking for the interface
    const std::string* controlService = nullptr;
    for (const auto& [serviceName, interfaceList] : serviceMap)
    {
        if (std::find(interfaceList.begin(), interfaceList.end(),
                      "xyz.openbmc_project.Control.Processor."
                      "CurrentOperatingConfig") != interfaceList.end())
        {
            controlService = &serviceName;
            break;
        }
    }

    if (controlService == nullptr)
    {
        messages::internalError(resp->res);
        return;
    }

    // Check that the config URI is a child of the cpu URI being patched.
    std::string expectedPrefix("/redfish/v1/Systems/system/Processors/");
    expectedPrefix += processorId;
    expectedPrefix += "/OperatingConfigs/";
    if (!appliedConfigUri.starts_with(expectedPrefix) ||
        expectedPrefix.size() == appliedConfigUri.size())
    {
        messages::propertyValueIncorrect(
            resp->res, "AppliedOperatingConfig/@odata.id", appliedConfigUri);
        return;
    }

    // Generate the D-Bus path of the OperatingConfig object, by assuming it's a
    // direct child of the CPU object.
    // Strip the expectedPrefix from the config URI to get the "filename", and
    // append to the CPU's path.
    std::string configBaseName = appliedConfigUri.substr(expectedPrefix.size());
    sdbusplus::message::object_path configPath(cpuObjectPath);
    configPath /= configBaseName;

    BMCWEB_LOG_INFO << "Setting config to " << configPath.str;

    // Set the property, with handler to check error responses
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        resp->strand_,
        [resp, appliedConfigUri](const boost::system::error_code& ec,
                                 const sdbusplus::message_t& msg) {
        handleAppliedConfigResponse(resp, appliedConfigUri, ec, msg);
    },
        *controlService, cpuObjectPath, "org.freedesktop.DBus.Properties",
        "Set", "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig",
        "AppliedConfig", dbus::utility::DbusVariantType(std::move(configPath)));
}

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

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

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

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

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

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

inline void parseSubtreeForProcessorCollection(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const dbus::utility::MapperGetSubTreeResponse& subtree,
    const query_param::Query& delegated, const std::string& systemPath)
{
    const bool multiHost = !systemPath.empty();

    // Default systemName is system and change if system is multi-host
    std::string systemName = "system";

    if (multiHost)
    {
        systemName = sdbusplus::message::object_path(systemPath).filename();
    }

    if (delegated.expandLevel == 0 ||
        delegated.expandType == query_param::ExpandType::None)
    {
        BMCWEB_LOG_DEBUG << "Use default processor expand handler";
        collection_util::getCollectionMembersFromSubtree(
            asyncResp,
            boost::urls::url("/redfish/v1/Systems/" + systemName +
                             "/Processors"),
            processorInterfaces, subtree);
        return;
    }
    BMCWEB_LOG_DEBUG << "Use efficient processor expand handler";

    std::vector<std::string> serviceNames =
        dbus_utils::getServiceNamesFromSubtree(subtree);
    if (serviceNames.empty())
    {
        BMCWEB_LOG_DEBUG << "Can't retrieve service names from subtree";
        asyncResp->res.jsonValue["Members@odata.count"] = 0;
        asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
        return;
    }

    managedStore::ManagedObjectStoreContext context(asyncResp);
    // Get managed objects from each service in subtree to proactively
    // fetch all dbus data needed to serve requests for subordinate
    // resources.
    sdbusplus::message::object_path path("/xyz/openbmc_project/inventory");
    dbus_utils::getManagedObjectsInEachService(
        std::move(serviceNames), path, context,
        [asyncResp{asyncResp}, subtree, delegated,
         systemPath](const ManagedObjectByServiceMap& managedObjectsByService) {
        if (managedObjectsByService.empty())
        {
            BMCWEB_LOG_DEBUG << "Cannot get managed objects.";
            messages::internalError(asyncResp->res);
            return;
        }
        getProcessorCollectionWithExpand(asyncResp, subtree,
                                         managedObjectsByService,
                                         delegated.expandLevel, systemPath);
    });
}

inline void handleProcessorCollection(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const query_param::Query& delegated, const std::string& systemPath)
{
    const bool multiHost = !systemPath.empty();

    // Default systemName is system and change if system is multi-host
    std::string systemName = "system";
    // The subtree to query for Dimms changes if single or multi-host
    std::string subtreeRoot = "/xyz/openbmc_project/inventory";

    if (multiHost)
    {
        systemName = sdbusplus::message::object_path(systemPath).filename();
        subtreeRoot = systemPath;
    }

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

    asyncResp->res.jsonValue["@odata.type"] =
        "#ProcessorCollection.ProcessorCollection";
    asyncResp->res.jsonValue["Name"] = "Processor Collection";

    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/Systems/" + systemName + "/Processors";

    // Get dbus interfaces based on expand level.
    auto interfaces = getInterfacesForProcessorSubtree(delegated.expandLevel);

    if (interfaces.empty())
    {
        BMCWEB_LOG_ERROR << "Can't get interface list for expand level "
                         << delegated.expandLevel;
        messages::internalError(asyncResp->res);
        return;
    }

    // Get subtree information to serve requests for both processor
    // collection and, if expand is requested, for all requested subordinate
    // resources.
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTree(
        subtreeRoot, 0, interfaces, requestContext,
        [asyncResp{asyncResp}, delegated,
         systemPath](const boost::system::error_code& ec,
                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec == boost::system::errc::io_error)
        {
            asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
            asyncResp->res.jsonValue["Members@odata.count"] = 0;
            return;
        }

        if (ec)
        {
            BMCWEB_LOG_DEBUG << "DBUS response error " << ec.value();
            messages::internalError(asyncResp->res);
            return;
        }
        parseSubtreeForProcessorCollection(asyncResp, subtree, delegated,
                                           systemPath);
    });
}

inline void handleOperatingConfigCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& cpuName)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    asyncResp->res.jsonValue["@odata.type"] =
        "#OperatingConfigCollection.OperatingConfigCollection";
    asyncResp->res.jsonValue["@odata.id"] =
        crow::utility::urlFromPieces("redfish", "v1", "Systems", "system",
                                     "Processors", cpuName, "OperatingConfigs");
    asyncResp->res.jsonValue["Name"] = "Operating Config Collection";

    // First find the matching CPU object so we know how to
    // constrain our search for related Config objects.
    const std::array<std::string_view, 1> interfaces = {
        "xyz.openbmc_project.Control.Processor.CurrentOperatingConfig"};
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTreePaths(
        "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
        [asyncResp,
         cpuName](const boost::system::error_code& ec,
                  const dbus::utility::MapperGetSubTreePathsResponse& objects) {
        if (ec)
        {
            BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", " << ec.message();
            messages::internalError(asyncResp->res);
            return;
        }

        for (const std::string& object : objects)
        {
            if (!object.ends_with(cpuName))
            {
                continue;
            }

            // Not expected that there will be multiple matching
            // CPU objects, but if there are just use the first
            // one.

            // Use the common search routine to construct the
            // Collection of all Config objects under this CPU.
            constexpr std::array<std::string_view, 1> interface{
                "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"};
            collection_util::getCollectionMembers(
                asyncResp,
                crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                             "system", "Processors", cpuName,
                                             "OperatingConfigs"),
                interface, object.c_str());
            return;
        }
    });
}

inline void requestRoutesOperatingConfigCollection(App& app)
{
    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/system/Processors/<str>/OperatingConfigs/")
        .privileges(redfish::privileges::getOperatingConfigCollection)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleOperatingConfigCollectionGet, std::ref(app)));
}

inline void handleOperatingConfigGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& cpuName, const std::string& configName)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    // Ask for all objects implementing OperatingConfig so we can search
    // for one with a matching name
    constexpr std::array<std::string_view, 1> interfaces = {
        "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"};
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTree(
        "/xyz/openbmc_project/inventory", 0, interfaces, requestContext,
        [asyncResp, cpuName,
         configName](const boost::system::error_code& ec,
                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec)
        {
            BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", " << ec.message();
            messages::internalError(asyncResp->res);
            return;
        }
        const std::string expectedEnding = cpuName + '/' + configName;
        for (const auto& [objectPath, serviceMap] : subtree)
        {
            // Ignore any configs without matching cpuX/configY
            if (!objectPath.ends_with(expectedEnding) || serviceMap.empty())
            {
                continue;
            }

            nlohmann::json& json = asyncResp->res.jsonValue;
            json["@odata.type"] = "#OperatingConfig.v1_0_0.OperatingConfig";
            json["@odata.id"] = crow::utility::urlFromPieces(
                "redfish", "v1", "Systems", "system", "Processors", cpuName,
                "OperatingConfigs", configName);
            json["Name"] = "Processor Profile";
            json["Id"] = configName;

            // Just use the first implementation of the object - not
            // expected that there would be multiple matching
            // services
            getOperatingConfigData(asyncResp, serviceMap.begin()->first,
                                   objectPath);
            return;
        }
        messages::resourceNotFound(asyncResp->res, "OperatingConfig",
                                   configName);
    });
}

inline void requestRoutesOperatingConfig(App& app)
{
    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Systems/system/Processors/<str>/OperatingConfigs/<str>/")
        .privileges(redfish::privileges::getOperatingConfig)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleOperatingConfigGet, std::ref(app)));
}

inline int countProcessors()
{
    // TODO(): This is a STUB
    // For now, this is OK, since it is only used for syntax validation.
    // However, when and if writing (POST, PATCH, etc.) is allowed,
    // we will need to have better bounds-checking here,
    // otherwise it will be trivial for a writer to DoS all the storage.
    return 16;
}

inline int countCores(int cpuIndex)
{
    // TODO(): This is a STUB, see above comment
    (void)cpuIndex;
    return 256;
}

inline int countThreads(int cpuIndex, int coreIndex)
{
    // TODO(): This is a STUB, see above comment
    (void)cpuIndex;
    (void)coreIndex;
    return 16;
}

inline int prefixStrToInt(const std::string& prefix, const std::string& str)
{
    size_t lenPrefix = prefix.size();
    size_t lenStr = str.size();

    // Content following prefix must be within 1 to 9 characters in length
    if (lenStr < (lenPrefix + 1))
    {
        BMCWEB_LOG_ERROR << "Index number too short";
        return -1;
    }
    if (lenStr > (lenPrefix + 9))
    {
        // This length limit prevents 32-bit rollover attacks
        BMCWEB_LOG_ERROR << "Index number too long";
        return -1;
    }

    if (str.substr(0, lenPrefix) != prefix)
    {
        // Prefix does not match
        BMCWEB_LOG_ERROR << "Index number wrong prefix";
        return -1;
    }

    std::string numText = str.substr(lenPrefix);
    size_t lenText = numText.size();
    size_t lenCheck = std::strlen(numText.c_str());
    if (lenText != lenCheck)
    {
        // This comparison prevents 0x00 string truncation attacks
        BMCWEB_LOG_ERROR << "Index number wrong length";
        return -1;
    }

    // Cannot use std::stoi because stoi throws
    char* endptr = nullptr;
    int64_t value = std::strtol(numText.c_str(), &endptr, 10);
    if (*endptr != '\0')
    {
        // The number was followed by extra content
        BMCWEB_LOG_ERROR << "Index number wrong content";
        return -1;
    }

    int result = static_cast<int>(value);
    return result;
}

inline int extractIndexFromArg(const std::string& arg)
{
    const std::string index =
        arg.substr(arg.find_last_not_of("0123456789") + 1);
    if (index.empty())
    {
        BMCWEB_LOG_ERROR << "Unable to extract index from arg";
        return -1;
    }
    // use std::strtol since std::stoi can throw
    char* enptr = nullptr;
    int64_t value = std::strtol(index.c_str(), &enptr, 10);
    return static_cast<int>(value);
}

inline int cpuArgToIndex(const std::string& cpuArg)
{
    int bound = countProcessors();
    int num = extractIndexFromArg(cpuArg);
    if (num >= bound)
    {
        BMCWEB_LOG_ERROR << "Processor index out of range";
        return -1;
    }
    return num;
}

inline int coreArgToIndex(const std::string& coreArg, int cpuIndex)
{

    int bound = countCores(cpuIndex);
    int num = prefixStrToInt("core", coreArg);
    if (num >= bound)
    {
        BMCWEB_LOG_ERROR << "Subprocessor core index out of range";
        return -1;
    }
    return num;
}

inline int threadArgToIndex(const std::string& threadArg, int cpuIndex,
                            int coreIndex)
{

    int bound = countThreads(cpuIndex, coreIndex);
    int num = prefixStrToInt("thread", threadArg);
    if (num >= bound)
    {
        BMCWEB_LOG_ERROR << "Subprocessor thread index out of range";
        return -1;
    }
    return num;
}

inline int validateCpu(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const std::string& cpuArg)
{
    int cpuIndex = cpuArgToIndex(cpuArg);
    if (cpuIndex < 0)
    {
        messages::resourceNotFound(asyncResp->res, "Processor", cpuArg);
    }
    return cpuIndex;
}

inline int validateCpuCore(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                           const std::string& cpuArg,
                           const std::string& coreArg)
{
    int cpuIndex = validateCpu(asyncResp, cpuArg);
    if (cpuIndex < 0)
    {
        return cpuIndex;
    }
    int coreIndex = coreArgToIndex(coreArg, cpuIndex);
    if (coreIndex < 0)
    {
        messages::resourceNotFound(asyncResp->res, "Core", coreArg);
    }
    return coreIndex;
}

inline int
    validateCpuCoreThread(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const std::string& cpuArg, const std::string& coreArg,
                          const std::string& threadArg)
{
    int cpuIndex = validateCpu(asyncResp, cpuArg);
    if (cpuIndex < 0)
    {
        return cpuIndex;
    }
    int coreIndex = validateCpuCore(asyncResp, cpuArg, coreArg);
    if (coreIndex < 0)
    {
        return coreIndex;
    }
    int threadIndex = threadArgToIndex(threadArg, cpuIndex, coreIndex);
    if (threadIndex < 0)
    {
        messages::resourceNotFound(asyncResp->res, "Thread", threadArg);
    }
    return threadIndex;
}

// Creates a generic ExternalStorer hook, should be 2 directories above
// Each hook contains instances, each instance contains entries
// Omit the leading "/redfish/v1" from pathBase, and no trailing slash
inline external_storer::Hook makeExternalStorerHook(const std::string& pathBase)
{
    const std::string emptyString;
    const std::vector<std::string> emptyList;

    return {pathBase, emptyString, emptyList, emptyList};
}

// Creates a generic ExternalStorer instance within the given hook
// The content will be minimal, just enough to create filename on disk
// Returns true if successful
inline bool makeExternalStorerInstance(
    const std::shared_ptr<external_storer::Hook>& hook, const std::string& id)
{
    // External storer NEVER sends dbus calls, so you will never leave this thread.
    auto respGet = std::make_shared<bmcweb::AsyncResp>(nullptr);

    hook->handleGetInstance(respGet, id);
    if (respGet->res.result() == boost::beast::http::status::ok)
    {
        // Already exists, nothing more needs to be done
        return true;
    }

    boost::beast::http::request<boost::beast::http::string_body> upBody;
    std::error_code ec;

    // Create instance, with given ID, which will become filename on disk
    auto upJson = nlohmann::json::object();
    upJson["Id"] = id;

    // Must supply 4th argument to avoid throwing exceptions
    upBody.body() =
        upJson.dump(-1, ' ', false, nlohmann::json::error_handler_t::replace);
    crow::Request reqCreate{upBody, ec};

    // External storer NEVER sends dbus calls, so you will never leave this thread.
    auto respCreate = std::make_shared<bmcweb::AsyncResp>(nullptr);

    hook->handleCreateInstance(reqCreate, respCreate);
    if (respCreate->res.result() != boost::beast::http::status::created)
    {
        BMCWEB_LOG_ERROR << "Problem creating ExternalStorer instance " << id;
        return false;
    }

    return true;
}

// Remembers toplevel Processors hook, there is only one
// Each instance in it represents a CPU and is named like cpuArg
// Each instance contains only one entry, "ProcessorMetrics"
inline std::shared_ptr<external_storer::Hook>
    rememberProcessorHook(const std::string& cpuArg)
{
    static std::shared_ptr<external_storer::Hook> hookProcessor = nullptr;

    if (!hookProcessor)
    {
        // If not already remembered by static variable, create hook
        hookProcessor = std::make_shared<external_storer::Hook>(
            makeExternalStorerHook("Systems/system/Processors"));
    }

    if (!(makeExternalStorerInstance(hookProcessor, cpuArg)))
    {
        BMCWEB_LOG_ERROR << "Problem remembering hook for " << cpuArg;
        return nullptr;
    }

    return hookProcessor;
}

// Remembers lowest-level SubProcessors hook
// There is one hook for each unique (CPU, thread) tuple
// Each instance in it represents a thread and is named like threadArg
// Each instance contains only one entry, "ProcessorMetrics"
inline std::shared_ptr<external_storer::Hook>
    rememberThreadHook(const std::string& cpuArg, const std::string& coreArg,
                       const std::string& threadArg)
{
    static std::map<
        std::string,
        std::map<std::string, std::shared_ptr<external_storer::Hook>>>
        hookMaps;

    auto findCpu = hookMaps.find(cpuArg);
    if (findCpu == hookMaps.end())
    {
        hookMaps[cpuArg] = {};
        findCpu = hookMaps.find(cpuArg);
    }

    auto findCore = findCpu->second.find(coreArg);
    if (findCore == findCpu->second.end())
    {
        (findCpu->second)[coreArg] = {};
        findCore = findCpu->second.find(coreArg);
    }

    std::shared_ptr<external_storer::Hook> hookThread = findCore->second;

    if (!hookThread)
    {
        std::string path = "Systems/system/Processors/" + cpuArg +
                           "/SubProcessors/" + coreArg + "/SubProcessors";
        hookThread = std::make_shared<external_storer::Hook>(
            makeExternalStorerHook(path));
        findCore->second = hookThread;
    }

    if (!(makeExternalStorerInstance(hookThread, threadArg)))
    {
        BMCWEB_LOG_ERROR << "Problem remembering hook for " << threadArg;
        return nullptr;
    }

    return hookThread;
}

inline nlohmann::json fakeProcessorMetrics(const std::string& cpu,
                                           const std::string& core,
                                           const std::string& thread)
{
    nlohmann::json::object_t metricsObj;

    metricsObj["Id"] = "Metrics";
    metricsObj["Name"] = "Processor Metrics";

    // The different levels have slightly different default content
    if (!thread.empty())
    {
        // Thread level
        metricsObj["CorrectableCoreErrorCount"] = 0;
        metricsObj["UncorrectableCoreErrorCount"] = 0;
    }
    metricsObj["CorrectableOtherErrorCount"] = 0;
    metricsObj["UncorrectableOtherErrorCount"] = 0;

    // ExternalStorer would normally apply this as invariant if successful
    // The caller already applies "@odata.type" as invariant no matter what
    std::string url = "/redfish/v1/Systems/system/Processors/";
    url += cpu;
    if (!core.empty())
    {
        url += "/SubProcessors/";
        url += core;
    }
    if (!thread.empty())
    {
        url += "/SubProcessors/";
        url += thread;
    }
    url += "/ProcessorMetrics";

    metricsObj["@odata.id"] = std::move(url);

    return metricsObj;
}

inline void
    handleGetCpuMetrics(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                        const nlohmann::json::json_pointer& jsonPtr,
                        const std::string& cpuArg)
{
    if (validateCpu(asyncResp, cpuArg) < 0)
    {
        // Error reply already composed
        return;
    }

    std::shared_ptr<external_storer::Hook> hook = rememberProcessorHook(cpuArg);
    if (!hook)
    {
        messages::resourceNotFound(asyncResp->res, "Processor", cpuArg);
        return;
    }

    std::string emptyString;
    hook->handleGetEntry(asyncResp, jsonPtr, cpuArg, emptyString,
                         "ProcessorMetrics");
    if (asyncResp->res.result() == boost::beast::http::status::not_found)
    {
        // Fake up a synthetic response to replace only the 404 error
        asyncResp->res.jsonValue[jsonPtr] =
            fakeProcessorMetrics(cpuArg, "", "");
        asyncResp->res.result(boost::beast::http::status::ok);
    }
    if (asyncResp->res.result() != boost::beast::http::status::ok)
    {
        // Error reply already composed
        return;
    }

    // Apply invariants, to override whatever might have been in the file
    asyncResp->res.jsonValue[jsonPtr]["@odata.type"] =
        "#ProcessorMetrics.v1_5_0.ProcessorMetrics";
}

inline void handleGetCpuCoreThreadMetrics(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const nlohmann::json::json_pointer& jsonPtr, const std::string& cpuArg,
    const std::string& coreArg, const std::string& threadArg)
{
    if (validateCpuCoreThread(asyncResp, cpuArg, coreArg, threadArg) < 0)
    {
        return;
    }

    std::shared_ptr<external_storer::Hook> hook =
        rememberThreadHook(cpuArg, coreArg, threadArg);
    if (!hook)
    {
        messages::resourceNotFound(asyncResp->res, "Thread", threadArg);
        return;
    }

    std::string emptyString;
    hook->handleGetEntry(asyncResp, jsonPtr, threadArg, emptyString,
                         "ProcessorMetrics");
    if (asyncResp->res.result() == boost::beast::http::status::not_found)
    {
        // Fake up a synthetic response to replace only the 404 error
        asyncResp->res.jsonValue[jsonPtr] =
            fakeProcessorMetrics(cpuArg, coreArg, threadArg);
        asyncResp->res.result(boost::beast::http::status::ok);
    }
    if (asyncResp->res.result() != boost::beast::http::status::ok)
    {
        // Error reply already composed
        return;
    }

    // Apply invariants, to override whatever might have been in the file
    asyncResp->res.jsonValue[jsonPtr]["@odata.type"] =
        "#ProcessorMetrics.v1_5_0.ProcessorMetrics";
}

// The glue layers are already handled by these functions elsewhere:
// Processors = requestRoutesProcessorCollection()
// Processors/cpuX = requestRoutesProcessor()
// Processors/cpuX/SubProcessors = requestRoutesSubProcessorCoreCollection()
// Processors/cpuX/SubProcessors/coreY = requestRoutesSubProcessorCore()
// Processors/cpuX/SubProcessors/coreY/SubProcessors =
// requestRoutesSubProcessorThreadCollection()
// Processors/cpuX/SubProcessors/coreY/SubProcessors/threadZ =
// requestRoutesSubProcessorThread()

// The "ProcessorMetrics" endpoints are below those glue layers:
// Processors/cpuX/ProcessorMetrics = handled here
// Processors/cpuX/SubProcessors/coreY/ProcessorMetrics = intentionally
// omitted
// Processors/cpuX/SubProcessors/coreY/SubProcessors/threadZ/ProcessorMetrics
// = handled here
inline void requestRoutesProcessorMetricsViaExternalStorer(App& app)
{
    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/system/Processors/<str>/ProcessorMetrics/")
        .privileges(redfish::privileges::getProcessor)
        .methods(boost::beast::http::verb::get)(
            [&app](const crow::Request& req,
                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                   const std::string& cpuArg) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }
        handleGetCpuMetrics(asyncResp, ""_json_pointer, cpuArg);
    });

    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Systems/system/Processors/<str>/SubProcessors/<str>/SubProcessors/<str>/ProcessorMetrics/")
        .privileges(redfish::privileges::getProcessor)
        .methods(boost::beast::http::verb::get)(
            [&app](const crow::Request& req,
                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                   const std::string& cpuArg, const std::string& coreArg,
                   const std::string& threadArg) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }
        handleGetCpuCoreThreadMetrics(asyncResp, ""_json_pointer, cpuArg,
                                      coreArg, threadArg);
    });

    // TODO(): Implement corresponding PATCH methods
    // The POST method is not correct to use here,
    // as the result location is already well-known name "ProcessorMetrics".
    // and from the user point of view it always exists,
    // so the creation operation is not the correct operation.
    // The PUT method also might not be correct to use here,
    // as it would fully replace all content at the result location,
    // but the expectation is to only selectively replace some content.
}

inline void requestRoutesProcessorCollection(App& app)
{
    /**
     * Functions triggers appropriate requests on DBus
     */
    BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/")
        .privileges(redfish::privileges::headProcessorCollection)
        .methods(boost::beast::http::verb::head)(
            std::bind_front(handleProcessorCollectionHead, std::ref(app)));

    BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/")
        .privileges(redfish::privileges::getProcessorCollection)
        .methods(boost::beast::http::verb::get)(
            [&app](const crow::Request& req,
                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                   const std::string& systemName) {
        query_param::Query delegated;
        query_param::QueryCapabilities capabilities = {
#ifdef EFFICIENT_EXPAND_PROCESSORS_ENABLED
            .canDelegateExpandLevel = 6,
#else
            .canDelegateExpandLevel = 0,
#endif
        };
        if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
                                                      delegated, capabilities))
        {
            return;
        }

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

inline void getProcessorStateCollection(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& processorId)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    constexpr std::array<std::string_view, 1> procStateIntf = {
        "xyz.openbmc_project.Inventory.Item.ProcessorState"};
    collection_util::getCollectionMembers(
        asyncResp,
        crow::utility::urlFromPieces("redfish", "v1", "Systems", systemName,
                                     "Processors", processorId, "Oem", "Google",
                                     "ProcessorStates"),
        procStateIntf);
}

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

    redfish::system_utils::getSystemInformation(
        asyncResp, systemName,
        [processorId](const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                      const std::string& systemPath) {
        getProcessorObject(asyncResp, processorId, systemPath,
                           std::bind_front(getProcessorData, asyncResp,
                                           ""_json_pointer, 0, processorId,
                                           systemPath));
    });
}

inline void
    handleProcessorPatch(App& app, const crow::Request& req,
                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                         const std::string& systemName,
                         const std::string& processorId)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    if (systemName != "system")
    {
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   systemName);
        return;
    }

    std::optional<nlohmann::json> appliedConfigJson;
    if (!json_util::readJsonPatch(req, asyncResp->res, "AppliedOperatingConfig",
                                  appliedConfigJson))
    {
        return;
    }

    if (appliedConfigJson)
    {
        std::string appliedConfigUri;
        if (!json_util::readJson(*appliedConfigJson, asyncResp->res,
                                 "@odata.id", appliedConfigUri))
        {
            return;
        }

        redfish::system_utils::getSystemInformation(
            asyncResp, systemName,
            [processorId, appliedConfigUri](
                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                const std::string& systemPath) {
            // Check for 404 and find matching D-Bus object, then run
            // property patch handlers if that all succeeds.
            getProcessorObject(asyncResp, processorId, systemPath,
                               std::bind_front(patchAppliedOperatingConfig,
                                               asyncResp, processorId,
                                               appliedConfigUri));
        });
    }
}

inline void requestRoutesProcessor(App& app)
{
    /**
     * Functions triggers appropriate requests on DBus
     */

    BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
        .privileges(redfish::privileges::headProcessor)
        .methods(boost::beast::http::verb::head)(
            std::bind_front(handleProcessorHead, std::ref(app)));

    BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Processors/<str>/")
        .privileges(redfish::privileges::getProcessor)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleProcessorGet, std::ref(app)));

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

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

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

inline void requestRoutesSubProcessorCoreCollection(App& app)
{
    BMCWEB_ROUTE(app,
                 "/redfish/v1/Systems/<str>/Processors/<str>/SubProcessors/")
        .privileges(redfish::privileges::headProcessorCollection)
        .methods(boost::beast::http::verb::head)(std::bind_front(
            handleSubProcessorCoreCollectionHead, std::ref(app)));

    BMCWEB_ROUTE(app,
                 "/redfish/v1/Systems/<str>/Processors/<str>/SubProcessors/")
        .privileges(redfish::privileges::getProcessorCollection)
        .methods(boost::beast::http::verb::get)(
            [&app](const crow::Request& req,
                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                   const std::string& systemName,
                   const std::string& processorId) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }

        BMCWEB_LOG_DEBUG << "Get available system sub processor core members.";

        getProcessorPaths(asyncResp, processorId,
                          std::bind_front(getSubProcessorCoreMembers, asyncResp,
                                          processorId));
    });
}

inline void requestRoutesSubProcessorCore(App& app)
{
    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/<str>/Processors/<str>/SubProcessors/<str>/")
        .privileges(redfish::privileges::headProcessor)
        .methods(boost::beast::http::verb::head)(
            std::bind_front(handleSubProcessorCoreHead, std::ref(app)));

    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/<str>/Processors/<str>/SubProcessors/<str>/")
        .privileges(redfish::privileges::getProcessor)
        .methods(boost::beast::http::verb::get)(
            [&app](const crow::Request& req,
                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                   const std::string& systemName,
                   const std::string& processorId, const std::string& coreId) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }

        BMCWEB_LOG_DEBUG
            << "Get available system sub processor core resources.";

        getProcessorPaths(asyncResp, processorId,
                          std::bind_front(getSubProcessorCoreData, asyncResp,
                                          processorId, coreId));
    });
}

inline void requestRoutesSubProcessorThreadCollection(App& app)
{
    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Systems/<str>/Processors/<str>/SubProcessors/<str>/SubProcessors/")
        .privileges(redfish::privileges::headProcessorCollection)
        .methods(boost::beast::http::verb::head)(std::bind_front(
            handleSubProcessorThreadCollectionHead, std::ref(app)));
    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Systems/<str>/Processors/<str>/SubProcessors/<str>/SubProcessors/")
        .privileges(redfish::privileges::getProcessorCollection)
        .methods(boost::beast::http::verb::get)(
            [&app](const crow::Request& req,
                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                   const std::string& systemName,
                   const std::string& processorId, const std::string& coreId) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }

        getSubProcessorCorePaths(asyncResp, processorId, coreId,
                                 std::bind_front(getSubProcessorThreadMembers,
                                                 asyncResp, processorId,
                                                 coreId));
    });
}

inline void requestRoutesSubProcessorThread(App& app)
{
    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Systems/<str>/Processors/<str>/SubProcessors/<str>/SubProcessors/<str>/")
        .privileges(redfish::privileges::headProcessor)
        .methods(boost::beast::http::verb::head)(
            std::bind_front(handleSubProcessorThreadHead, std::ref(app)));
    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Systems/<str>/Processors/<str>/SubProcessors/<str>/SubProcessors/<str>/")
        .privileges(redfish::privileges::getProcessor)
        .methods(boost::beast::http::verb::get)(
            [&app](const crow::Request& req,
                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                   const std::string& systemName,
                   const std::string& processorId, const std::string& coreId,
                   const std::string& threadId) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }

        getSubProcessorCorePaths(asyncResp, processorId, coreId,
                                 std::bind_front(getSubProcessorThreadData,
                                                 asyncResp, processorId, coreId,
                                                 threadId));
    });
}

} // namespace redfish
