#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_MEMORY_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_MEMORY_H_

/*
// 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.
*/

#include <array>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#include "absl/strings/numbers.h"
#include "boost/system/error_code.hpp"  // NOLINT
#include "app.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "collection.hpp"
#include "dbus_utils.hpp"
#include "hex_utils.hpp"
#include "json_utils.hpp"
#include "system_utils.hpp"
#include "external_storer.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message/native_types.hpp"
#include "sdbusplus/unpack_properties.hpp"

#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_last_not_of("0123456789") + 1);
  if (index.empty()) {
    BMCWEB_LOG_ERROR << "Unable to extract index from dimmId";
    return false;
  }

  int64_t index_value = 0;
  if (!absl::SimpleAtoi(index, &index_value)) {
    BMCWEB_LOG_ERROR << "DIMM index not parseable";
    return false;
  }

  if (index_value >= 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

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_MEMORY_H_
