/*
// 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 "external_storer.hpp"
#include "health.hpp"
#include "http_utility.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/system_utils.hpp"

#include <boost/system/error_code.hpp>
#include <nlohmann/json.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/unpack_properties.hpp>

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

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

namespace redfish
{

inline std::string translateMemoryTypeToRedfish(const std::string& memoryType)
{
    if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR")
    {
        return "DDR";
    }
    if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2")
    {
        return "DDR2";
    }
    if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3")
    {
        return "DDR3";
    }
    if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4")
    {
        return "DDR4";
    }
    if (memoryType ==
        "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM")
    {
        return "DDR4E_SDRAM";
    }
    if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5")
    {
        return "DDR5";
    }
    if (memoryType ==
        "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM")
    {
        return "LPDDR4_SDRAM";
    }
    if (memoryType ==
        "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM")
    {
        return "LPDDR3_SDRAM";
    }
    if (memoryType ==
        "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM")
    {
        return "DDR2_SDRAM_FB_DIMM";
    }
    if (memoryType ==
        "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB")
    {
        return "DDR2_SDRAM_FB_DIMM_PROBE";
    }
    if (memoryType ==
        "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM")
    {
        return "DDR_SGRAM";
    }
    if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM")
    {
        return "ROM";
    }
    if (memoryType ==
        "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM")
    {
        return "SDRAM";
    }
    if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO")
    {
        return "EDO";
    }
    if (memoryType ==
        "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode")
    {
        return "FastPageMode";
    }
    if (memoryType ==
        "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble")
    {
        return "PipelinedNibble";
    }
    if (memoryType ==
        "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical")
    {
        return "Logical";
    }
    if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM")
    {
        return "HBM";
    }
    if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2")
    {
        return "HBM2";
    }
    if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3")
    {
        return "HBM3";
    }
    // This is values like Other or Unknown
    // Also D-Bus values:
    // DRAM
    // EDRAM
    // VRAM
    // SRAM
    // RAM
    // FLASH
    // EEPROM
    // FEPROM
    // EPROM
    // CDRAM
    // ThreeDRAM
    // RDRAM
    // FBD2
    // LPDDR_SDRAM
    // LPDDR2_SDRAM
    // LPDDR5_SDRAM
    return "";
}

inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                          const char* key, const uint16_t* value,
                          const nlohmann::json::json_pointer& jsonPtr)
{
    if (value == nullptr)
    {
        return;
    }
    aResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
}

inline void getPersistentMemoryProperties(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const dbus::utility::DBusPropertiesMap& properties,
    const nlohmann::json::json_pointer& jsonPtr)
{
    const uint16_t* moduleManufacturerID = nullptr;
    const uint16_t* moduleProductID = nullptr;
    const uint16_t* subsystemVendorID = nullptr;
    const uint16_t* subsystemDeviceID = nullptr;
    const uint64_t* volatileRegionSizeLimitInKiB = nullptr;
    const uint64_t* pmRegionSizeLimitInKiB = nullptr;
    const uint64_t* volatileSizeInKiB = nullptr;
    const uint64_t* pmSizeInKiB = nullptr;
    const uint64_t* cacheSizeInKB = nullptr;
    const uint64_t* voltaileRegionMaxSizeInKib = nullptr;
    const uint64_t* pmRegionMaxSizeInKiB = nullptr;
    const uint64_t* allocationIncrementInKiB = nullptr;
    const uint64_t* allocationAlignmentInKiB = nullptr;
    const uint64_t* volatileRegionNumberLimit = nullptr;
    const uint64_t* pmRegionNumberLimit = nullptr;
    const uint64_t* spareDeviceCount = nullptr;
    const bool* isSpareDeviceInUse = nullptr;
    const bool* isRankSpareEnabled = nullptr;
    const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr;
    const bool* configurationLocked = nullptr;
    const std::string* allowedMemoryModes = nullptr;
    const std::string* memoryMedia = nullptr;
    const bool* configurationLockCapable = nullptr;
    const bool* dataLockCapable = nullptr;
    const bool* passphraseCapable = nullptr;
    const uint64_t* maxPassphraseCount = nullptr;
    const uint64_t* passphraseLockLimit = nullptr;

    const bool success = sdbusplus::unpackPropertiesNoThrow(
        dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID",
        moduleManufacturerID, "ModuleProductID", moduleProductID,
        "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID",
        subsystemDeviceID, "VolatileRegionSizeLimitInKiB",
        volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB",
        pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB,
        "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB,
        "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib,
        "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB,
        "AllocationIncrementInKiB", allocationIncrementInKiB,
        "AllocationAlignmentInKiB", allocationAlignmentInKiB,
        "VolatileRegionNumberLimit", volatileRegionNumberLimit,
        "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount",
        spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse,
        "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW",
        maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked,
        "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia,
        "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable",
        dataLockCapable, "PassphraseCapable", passphraseCapable,
        "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit",
        passphraseLockLimit);

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

    dimmPropToHex(aResp, "ModuleManufacturerID", moduleManufacturerID, jsonPtr);
    dimmPropToHex(aResp, "ModuleProductID", moduleProductID, jsonPtr);
    dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID",
                  subsystemVendorID, jsonPtr);
    dimmPropToHex(aResp, "MemorySubsystemControllerProductID",
                  subsystemDeviceID, jsonPtr);

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

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

    if (volatileSizeInKiB != nullptr)
    {

        aResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] =
            (*volatileSizeInKiB) >> 10;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

    if (allowedMemoryModes != nullptr)
    {
        constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
                                                          "Block"};

        for (const char* v : values)
        {
            if (allowedMemoryModes->ends_with(v))
            {
                aResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"].emplace_back(
                    v);
                break;
            }
        }
    }

    if (memoryMedia != nullptr)
    {
        constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
                                                          "Intel3DXPoint"};

        for (const char* v : values)
        {
            if (memoryMedia->ends_with(v))
            {
                aResp->res.jsonValue[jsonPtr]["MemoryMedia"].emplace_back(v);
                break;
            }
        }
    }

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

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

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

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

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

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

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    dbus_utils::getProperty<std::vector<std::string>>(
        "xyz.openbmc_project.ObjectMapper", objectPath + "/processor",
        "xyz.openbmc_project.Association", "endpoints", requestContext,
        [asyncResp, jsonPtr](const boost::system::error_code ec,
                             const std::vector<std::string>& processorList) {
        if (ec)
        {
            return;
        }
        if (processorList.empty())
        {
            return;
        }
        nlohmann::json::array_t processorLinks;
        for (std::string_view processor : processorList)
        {
            sdbusplus::message::object_path processorPath(processor.data());
            // Define as `std::string` for easier concatenation later.
            const std::string processorName = processorPath.filename();
            if (processorName.empty())
            {
                BMCWEB_LOG_ERROR << "filename() is empty in "
                                 << processorPath.str;
                return;
            }
            nlohmann::json::object_t processorObject;
            processorObject["@odata.id"] =
                "/redfish/v1/Systems/system/Processors/" + processorName;
            processorLinks.emplace_back(processorObject);
        }
        asyncResp->res.jsonValue[jsonPtr]["Links"]["Processors"] =
            std::move(processorLinks);
    });
}

inline void
    assembleDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                           const dbus::utility::DBusPropertiesMap& properties,
                           const nlohmann::json::json_pointer& jsonPtr)
{
    const uint16_t* memoryDataWidth = nullptr;
    const size_t* memorySizeInKB = nullptr;
    const std::string* partNumber = nullptr;
    const std::string* serialNumber = nullptr;
    const std::string* manufacturer = nullptr;
    const uint16_t* revisionCode = nullptr;
    const bool* present = nullptr;
    const uint16_t* memoryTotalWidth = nullptr;
    const std::string* ecc = nullptr;
    const std::string* formFactor = nullptr;
    const std::vector<uint16_t>* allowedSpeedsMT = nullptr;
    const size_t* memoryAttributes = nullptr;
    const uint16_t* memoryConfiguredSpeedInMhz = nullptr;
    const std::string* memoryType = nullptr;
    const uint8_t* channel = nullptr;
    const uint8_t* memoryController = nullptr;
    const uint8_t* slot = nullptr;
    const uint8_t* socket = nullptr;
    const std::string* sparePartNumber = nullptr;
    const std::string* model = nullptr;
    const std::string* locationCode = nullptr;

    const bool success = sdbusplus::unpackPropertiesNoThrow(
        dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth",
        memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber",
        partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
        "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth",
        memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor,
        "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes",
        memoryAttributes, "MemoryConfiguredSpeedInMhz",
        memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel",
        channel, "MemoryController", memoryController, "Slot", slot, "Socket",
        socket, "SparePartNumber", sparePartNumber, "Model", model,
        "LocationCode", locationCode);

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

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

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

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

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

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

    if (revisionCode != nullptr)
    {
        aResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
            std::to_string(*revisionCode);
    }

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

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

    if (ecc != nullptr)
    {
        constexpr const std::array<const char*, 4> values{
            "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};

        for (const char* v : values)
        {
            if (ecc->ends_with(v))
            {
                aResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
                break;
            }
        }
    }

    if (formFactor != nullptr)
    {
        constexpr const std::array<const char*, 11> values{
            "RDIMM",       "UDIMM",       "SO_DIMM",      "LRDIMM",
            "Mini_RDIMM",  "Mini_UDIMM",  "SO_RDIMM_72b", "SO_UDIMM_72b",
            "SO_DIMM_16b", "SO_DIMM_32b", "Die"};

        for (const char* v : values)
        {
            if (formFactor->ends_with(v))
            {
                aResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
                break;
            }
        }
    }

    if (allowedSpeedsMT != nullptr)
    {
        nlohmann::json& jValue =
            aResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
        jValue = nlohmann::json::array();
        for (uint16_t subVal : *allowedSpeedsMT)
        {
            jValue.emplace_back(subVal);
        }
    }

    if (memoryAttributes != nullptr)
    {
        aResp->res.jsonValue[jsonPtr]["RankCount"] =
            static_cast<size_t>(*memoryAttributes);
    }

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

    if (memoryType != nullptr)
    {
        std::string memoryDeviceType =
            translateMemoryTypeToRedfish(*memoryType);
        // Values like "Unknown" or "Other" will return empty
        // so just leave off
        if (!memoryDeviceType.empty())
        {
            aResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
                memoryDeviceType;
        }
        if (memoryType->find("DDR") != std::string::npos)
        {
            aResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM";
        }
        else if (memoryType->ends_with("Logical"))
        {
            aResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane";
        }
    }

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

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

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

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

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

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

    if (locationCode != nullptr)
    {
        aResp->res
            .jsonValue[jsonPtr]["Location"]["PartLocation"]["ServiceLabel"] =
            *locationCode;
    }

    getPersistentMemoryProperties(aResp, properties, jsonPtr);
}

inline void getAllDimmsCallback(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::optional<std::string>& dimmId,
    const std::string& systemPath,
    const std::unordered_map<std::string, dbus::utility::ManagedObjectType>&
        managedObjectsByService
    )
{
    BMCWEB_LOG_DEBUG << "getAllDimmsCallback entered";
    nlohmann::json& jsonValue = asyncResp->res.jsonValue;
    for (const auto& [_, objects] : managedObjectsByService) {
        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();
        }

        for (const auto& [objectPath, interfaces] : objects)
        {
            // For multi-host systems, the object path of the Dimm must be a
            // descendant of the systemPath. (e.g. if systemPath = /a/b, then
            // objectPath must be some pattern like /a/b/..)
            if (multiHost && !std::string(objectPath).starts_with(systemPath))
            {
                continue;
            }

            std::string thisDimmID = objectPath.filename();
            if (thisDimmID.empty())
            {
                continue;
            }
            if (dimmId && *dimmId != thisDimmID)
            {
                continue;
            }
            bool hasDimmInterface = false;
            for (const auto& [interface, _] : interfaces)
            {
                if (interface == "xyz.openbmc_project.Inventory.Item.Dimm")
                {
                    hasDimmInterface = true;
                    break;
                }
            }
            if (!hasDimmInterface)
            {
                continue;
            }
            BMCWEB_LOG_DEBUG << "Found a dimm; objectPath=" << objectPath.str;
            nlohmann::json::json_pointer healthPtr;
            nlohmann::json::json_pointer dimmPtr;
            if (!dimmId)
            {
                size_t index =
                    jsonValue["Members"]
                        .size();
                healthPtr = "/Members"_json_pointer / index / "Status";
                dimmPtr = "/Members"_json_pointer / index;
            }
            else
            {
                healthPtr = "/Status"_json_pointer;
                dimmPtr = ""_json_pointer;
            }
            jsonValue[dimmPtr]["Id"] = thisDimmID;
            jsonValue[dimmPtr]["Name"] = "DIMM Slot";
            jsonValue[dimmPtr]["Status"]["State"] = "Enabled";
            jsonValue[dimmPtr]["Status"]["Health"] = "OK";
            jsonValue[dimmPtr]["@odata.id"] =
                crow::utility::urlFromPieces("redfish", "v1", "Systems", systemName,
                                             "Memory", thisDimmID);
            jsonValue[dimmPtr]["@odata.type"] = "#Memory.v1_11_0.Memory";

            // Memory Metrics are only implemented in single-host systems as of now
            if (systemName == "system")
            {
                // Inserting the "Metrics" JSON stanza
                std::string metricsUrl = jsonValue[dimmPtr]["@odata.id"];
                metricsUrl += "/MemoryMetrics";
                nlohmann::json::object_t metricsObj;
                metricsObj["@odata.id"] = std::move(metricsUrl);
                jsonValue[dimmPtr]["Metrics"] = std::move(metricsObj);
            }

            for (const auto& [interface, properties] : interfaces)
            {
                assembleDimmProperties(asyncResp, properties, dimmPtr);
                if (interface == "xyz.openbmc_project.Inventory.Connector.Slot")
                {
                   jsonValue[dimmPtr]["Location"]["PartLocation"]["LocationType"] = "Slot";
                }
                if (interface == "xyz.openbmc_project.Inventory.Connector.Embedded")
                {
                    jsonValue[dimmPtr]["Location"]["PartLocation"]["LocationType"] = "Embedded";
                }
            }
            getProcessorLinks(asyncResp, objectPath, dimmPtr);
        }
        if (!dimmId)
        {
            jsonValue["Members@odata.count"] = jsonValue["Members"].size();
        }
    }
    auto it = asyncResp->res.jsonValue.find("Members");
    if (it == asyncResp->res.jsonValue.end())
    {
        return;
    }
    auto* members = it->get_ptr<nlohmann::json::array_t*>();
    if (members == nullptr)
    {
        BMCWEB_LOG_ERROR << "Members is not array?!";
        messages::internalError(asyncResp->res);
        return;
    }
    if (!json_util::sortJsonArrayByKey("@odata.id", *members))
    {
        BMCWEB_LOG_ERROR << "Unable to sort the DIMM collection";
        messages::internalError(asyncResp->res);
        return;
    }
}

inline void getAllDimms(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::optional<std::string>& dimmId,
    const std::string& systemPath,
    std::vector<std::string>&& services)
{
    if (!dimmId)
    {
        asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
        asyncResp->res.jsonValue["Members@odata.count"] = 0;
    }

    managedStore::ManagedObjectStoreContext context(asyncResp);
    dbus_utils::getManagedObjectsInEachService(
        std::move(services), {"/xyz/openbmc_project/inventory"}, context,
        [dimmId{dimmId}, systemPath, asyncResp{asyncResp}]
        (const std::unordered_map<std::string, dbus::utility::ManagedObjectType>&
            managedObjectsByService) {
        getAllDimmsCallback(asyncResp, dimmId, systemPath, managedObjectsByService);
    });
}

// If |dimmId| is set, will only keep the first matched dimmId.
inline void getDimmData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                        const std::optional<std::string>& dimmId,
                        const std::string& subtreeRoot,
                        const std::string& systemPath)
{
    constexpr std::array<std::string_view, 1> dimmInterfaces = {
        "xyz.openbmc_project.Inventory.Item.Dimm"};
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTree(
        subtreeRoot, 0, dimmInterfaces, requestContext,
        [asyncResp{asyncResp}, dimmId,
         systemPath](const boost::system::error_code& ec,
                     const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "DBUS response error";
            messages::internalError(asyncResp->res);
            return;
        }
        BMCWEB_LOG_DEBUG
            << "Collect services that implement DIMM interface for "
            << dimmId.value_or("all DIMMs");
        bool foundGivenDimm = false;
        std::unordered_set<std::string> dimmServices;
        for (const auto& [path, object] : subtree)
        {
            BMCWEB_LOG_DEBUG << "Object path=" << path;
            sdbusplus::message::object_path objectPath(path);
            for (const auto& [service, interfaces] : object)
            {
                for (const std::string& interface : interfaces)
                {
                    if (interface == "xyz.openbmc_project.Inventory.Item.Dimm")
                    {
                        if (dimmId && objectPath.filename() != *dimmId)
                        {
                            continue;
                        }
                        BMCWEB_LOG_DEBUG << "Added DIMM services " << service;
                        dimmServices.insert(service);
                        foundGivenDimm = true;
                    }
                }
            }
            // Fetch the first matched DIMM
            if (dimmId && foundGivenDimm)
            {
                break;
            }
        }
        if (dimmId && !foundGivenDimm)
        {
            messages::resourceNotFound(asyncResp->res, "Memory", *dimmId);
            return;
        }
        std::vector<std::string> dimmServicesVec = {dimmServices.begin(), dimmServices.end()};
        getAllDimms(asyncResp, dimmId, systemPath, std::move(dimmServicesVec));
    });
}

inline void
    handleMemoryCollection(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                           const std::string& systemPath,
                           const query_param::Query& delegated)
{
    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.jsonValue["@odata.type"] =
        "#MemoryCollection.MemoryCollection";
    asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/Systems/" + systemName + "/Memory";

    constexpr std::array<std::string_view, 1> interfaces{
        "xyz.openbmc_project.Inventory.Item.Dimm"};
    if (delegated.expandLevel > 0 &&
        delegated.expandType != query_param::ExpandType::None)
    {
        BMCWEB_LOG_DEBUG << "Use efficient expand handler";
        getDimmData(asyncResp, std::nullopt, subtreeRoot, systemPath);
    }
    else
    {
        BMCWEB_LOG_DEBUG << "Use default expand handler";
        collection_util::getCollectionMembers(
            asyncResp,
            boost::urls::url("/redfish/v1/Systems/" + systemName + "/Memory"),
            interfaces, subtreeRoot.c_str());
    }
}

inline void handleMemoryCollectionGet(
    App& 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_MEMORY_ENABLED
        .canDelegateExpandLevel = 1,
#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) {
        handleMemoryCollection(asyncResp, systemPath, delegated);
    });
}

inline void requestRoutesMemoryCollection(App& app)
{
    /**
     * Functions triggers appropriate requests on DBus
     */
    BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/")
        .privileges(redfish::privileges::getMemoryCollection)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleMemoryCollectionGet, std::ref(app)));
}

// Constructs hook with known-good settings for use with MemoryMetrics
inline external_storer::Hook makeDimmHook()
{
    const std::string pathBase{"Systems/system/Memory"};

    const std::string emptyString;
    const std::vector<std::string> emptyList;

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

// Remembers the ExternalStorer hook and one instance per DIMM in this system
inline std::shared_ptr<external_storer::Hook>
    rememberDimmHook(const std::string& dimmId)
{
    static std::shared_ptr<external_storer::Hook> hookMemory = nullptr;

    if (!hookMemory)
    {
        // If not already remembered by static variable, create hook
        hookMemory = std::make_shared<external_storer::Hook>(makeDimmHook());
    }

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

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

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

    // Create instance, with name of DIMM, and no further customizations
    auto upJson = nlohmann::json::object();
    upJson["Id"] = dimmId;

    // 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);
    hookMemory->handleCreateInstance(reqCreate, respCreate);
    if (respCreate->res.result() != boost::beast::http::status::created)
    {
        BMCWEB_LOG_ERROR << "Problem creating instance for " << dimmId;
        return nullptr;
    }

    // The instance should now be usable
    return hookMemory;
}

inline nlohmann::json fakeMemoryMetrics(const std::string& dimm)
{
    nlohmann::json::object_t metricsObj;

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

    nlohmann::json::object_t currentPeriod;

    currentPeriod["CorrectableECCErrorCount"] = 0;
    currentPeriod["UncorrectableECCErrorCount"] = 0;
    currentPeriod["IndeterminateCorrectableErrorCount"] = 0;
    currentPeriod["IndeterminateUncorrectableErrorCount"] = 0;

    metricsObj["CurrentPeriod"] = std::move(currentPeriod);

    // 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/Memory/";
    url += dimm;
    url += "/MemoryMetrics";

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

    return metricsObj;
}

inline int countDimm()
{
    // TODO(): This is a STUB
    return 256;
}

inline bool checkDimmIndex(const std::string& dimmId)
{
    int bound = countDimm();

    // extract index from end of dimmId
    const std::string index =
        dimmId.substr(dimmId.find_first_not_of("0123456789") + 1);
    if (index.empty())
    {
        BMCWEB_LOG_ERROR << "Unable to extract index from dimmId";
        return false;
    }
    // use std::strtol since std::stoi can throw
    char* endptr = nullptr;
    int64_t value = std::strtol(index.c_str(), &endptr, 10);

    int num = static_cast<int>(value);

    if (num < 0)
    {
        BMCWEB_LOG_ERROR << "DIMM index not parseable";
        return false;
    }
    if (num >= bound)
    {
        BMCWEB_LOG_ERROR << "DIMM index out of range";
        return false;
    }

    return true;
}

inline bool getExternalStorerMemoryMetrics(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, const std::string& dimmId)
{
    if (!checkDimmIndex(dimmId))
    {
        BMCWEB_LOG_ERROR << "Problem checking DIMM index for " << dimmId;
        return false;
    }

    std::shared_ptr<external_storer::Hook> hook = rememberDimmHook(dimmId);
    if (!hook)
    {
        BMCWEB_LOG_ERROR << "Problem getting hook for " << dimmId;
        return false;
    }

    std::string emptyString;
    hook->handleGetEntry(aResp, ""_json_pointer, dimmId, emptyString,
                         "MemoryMetrics");
    if (aResp->res.result() == boost::beast::http::status::not_found)
    {
        // Fake up a synthetic response to replace only the 404 error
        aResp->res.jsonValue = fakeMemoryMetrics(dimmId);
        aResp->res.result(boost::beast::http::status::ok);
    }
    if (aResp->res.result() != boost::beast::http::status::ok)
    {
        BMCWEB_LOG_ERROR << "Problem getting file for " << dimmId;
        return false;
    }

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

    return true;
}

inline void getMemoryMetrics(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                             const std::string& dimmId)
{
    BMCWEB_LOG_DEBUG << "Get available memory metrics for DIMM.";

    // This is the integration point for ExternalStorer with MemoryMetrics.
    // If locally-existing file exists, use ExternalStorer to return it.
    if (getExternalStorerMemoryMetrics(aResp, dimmId))
    {
        BMCWEB_LOG_DEBUG << "Successful local file read for " << dimmId;
        return;
    }

    // No more falling back to D-Bus query, instead, simply give user 404
    BMCWEB_LOG_WARNING << "Memory metrics not found for " << dimmId;
    messages::resourceNotFound(aResp->res, "MemoryMetrics", dimmId);
}

inline void handleMemory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                         const std::string& systemPath,
                         const std::string& dimmId)
{
    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;
    }

    getDimmData(asyncResp, dimmId, subtreeRoot, systemPath);
}

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

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

inline void requestRoutesMemory(App& app)
{
    /**
     * Functions triggers appropriate requests on DBus
     */
    BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/")
        .privileges(redfish::privileges::getMemory)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleMemoryGet, std::ref(app)));
}

inline void
    handleMemoryMetricsGet(App& app, const crow::Request& req,
                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                           const std::string& dimmId)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    asyncResp->res.jsonValue["@odata.type"] =
        "#MemoryMetrics.v1_5_0.MemoryMetrics";
    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/Systems/system/Memory/" + dimmId + "/MemoryMetrics";

    getMemoryMetrics(asyncResp, dimmId);
}

inline void requestRoutesMemoryMetricsViaExternalStorer(App& app)
{
    /**
     * Functions triggers appropriate requests on DBus
     */
    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/MemoryMetrics/")
        .privileges(redfish::privileges::getMemoryMetrics)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleMemoryMetricsGet, std::ref(app)));
}

} // namespace redfish
