#include "log_services.hpp"

#include <systemd/sd-bus.h>
#include <systemd/sd-journal.h>
#include <tinyxml2.h>
#include <unistd.h>

#include <algorithm>
#include <array>
#include <cerrno>
#include <charconv>
#include <chrono>  // NOLINT
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <filesystem>  // NOLINT
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iostream>
#include <iterator>
#include <memory>
#include <optional>
#include <span>  // NOLINT
#include <sstream>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT
#include <tuple>
#include <unordered_map>
#include <utility>
#include <variant>
#include <vector>

#include "absl/strings/match.h"
#include "absl/strings/numbers.h"
#include "boost/algorithm/string/case_conv.hpp"  // NOLINT
#include "boost/algorithm/string/classification.hpp"  // NOLINT
#include "boost/algorithm/string/replace.hpp"  // NOLINT
#include "boost/algorithm/string/split.hpp"  // NOLINT
#include "boost/beast/core/detail/base64.hpp"  // NOLINT
#include "boost/beast/http/verb.hpp"  // NOLINT
#include "boost/container/flat_map.hpp"  // NOLINT
#include "boost/system/linux_error.hpp"  // NOLINT
#include "bmcweb_config.h"
#include "app.hpp"
#include "http_request.hpp"
#include "http_response.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "http_utility.hpp"
#include "human_sort.hpp"
#include "str_utility.hpp"
#include "error_messages.hpp"
#include "generated/enums/log_entry.hpp"
#include "gzfile.hpp"
#include "query.hpp"
#include "registries.hpp"
#include "registries/privilege_registry.hpp"
#include "task_messages.hpp"
#include "dbus_utils.hpp"
#include "json_utils.hpp"
#include "system_utils.hpp"
#include "time_utils.hpp"
#include "external_storer.hpp"  // NOLINT(misc-include-cleaner)
#include "task.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message.hpp"
#include "sdbusplus/message/native_types.hpp"
#include "sdbusplus/unpack_properties.hpp"  // NOLINT

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

namespace redfish {
#ifdef BMCWEB_ENABLE_RASMANAGER_EVENT_LOG
constexpr char const* rasManagerObject = "com.intel.RAS";
constexpr char const* rasManagerPath = "/com/intel/ras/logs";
#endif

constexpr char const* crashdumpObject =
    bmcwebEnableAmd ? "com.amd.crashdump" : "com.intel.crashdump";
constexpr char const* crashdumpPath =
    bmcwebEnableAmd ? "/com/amd/crashdump" : "/com/intel/crashdump";
constexpr char const* crashdumpInterface =
    bmcwebEnableAmd ? "com.amd.crashdump" : "com.intel.crashdump";
constexpr char const* deleteAllInterface =
    "xyz.openbmc_project.Collection.DeleteAll";
constexpr char const* crashdumpOnDemandInterface =
    bmcwebEnableAmd ? "com.amd.crashdump.OnDemand"
                    : "com.intel.crashdump.OnDemand";
constexpr char const* crashdumpTelemetryInterface =
    bmcwebEnableAmd ? "com.amd.crashdump.Telemetry"
                    : "com.intel.crashdump.Telemetry";
constexpr char const* pprFileInterface =
    "xyz.openbmc_project.PostPackageRepair.PprData";
constexpr char const* pprFileObject = "xyz.openbmc_project.PostPackageRepair";
constexpr char const* pprFilePath = "/xyz/openbmc_project/PostPackageRepair";
constexpr char const* defaultLogPrefix = "log";
constexpr uint64_t kMaxRuntimePPRCount = 8;
constexpr uint64_t kPPRTypeBoottimeMask = 0x8000;
constexpr uint16_t kBtSetToHardMask = 0x01;
constexpr uint16_t kRtToBtMask = 0x02;

enum class DumpCreationProgress : std::uint8_t {
  DUMP_CREATE_SUCCESS,
  DUMP_CREATE_FAILED,
  DUMP_CREATE_INPROGRESS
};

std::string dumpTypeToString(DumpType dumpType) {
  return std::string(dumpTypeStrings[static_cast<size_t>(dumpType)]);
}

inline std::string bootTimeDataTypeToString(const BootTimeDataType dataType) {
  return std::string(bootTimeDataTypeString[static_cast<size_t>(dataType)]);
}

inline static int getJournalMetadata(sd_journal* journal,
                                     std::string_view field,
                                     std::string_view& contents) {
  const char* data = nullptr;
  size_t length = 0;
  int ret = 0;
  // Get the metadata from the requested field of the journal entry
  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
  const void** dataVoid = reinterpret_cast<const void**>(&data);

  ret = sd_journal_get_data(journal, field.data(), dataVoid, &length);
  if (ret < 0) {
    return ret;
  }
  contents = std::string_view(data, length);
  // Only use the content after the "=" character.
  contents.remove_prefix(std::min(contents.find('=') + 1, contents.size()));
  return ret;
}

inline static int getJournalMetadataToInt64(sd_journal* journal,
                                            std::string_view field,
                                            int64_t& contents) {
  int ret = 0;
  std::string_view metadata;
  // Get the metadata from the requested field of the journal entry
  ret = getJournalMetadata(journal, field, metadata);
  if (ret < 0) {
    return ret;
  }

  bool parsed = absl::SimpleAtoi(metadata, &contents);

  if (!parsed) {
    BMCWEB_LOG_ERROR
        << "getJournalMetadata: Failed to parse metadata(severity): "
        << metadata;
    return -EINVAL;
  }

  return ret;
}

inline static bool getEntryTimestamp(sd_journal* journal,
                                     std::string& entryTimestamp) {
  int ret = 0;
  uint64_t timestamp = 0;
  ret = sd_journal_get_realtime_usec(journal, &timestamp);
  if (ret < 0) {
    BMCWEB_LOG_ERROR << "Failed to read entry timestamp: " << strerror(-ret);
    return false;
  }
  entryTimestamp = redfish::time_utils::getDateTimeUintUs(timestamp);
  return true;
}

inline static bool getUniqueEntryID(sd_journal* journal, std::string& entryID,
                                    const bool firstEntry = true) {
  int ret = 0;
  static uint64_t prevTs = 0;
  static int index = 0;
  if (firstEntry) {
    prevTs = 0;
  }

  // Get the entry timestamp
  uint64_t curTs = 0;
  ret = sd_journal_get_realtime_usec(journal, &curTs);
  if (ret < 0) {
    BMCWEB_LOG_ERROR << "Failed to read entry timestamp: " << strerror(-ret);
    return false;
  }
  // If the timestamp isn't unique, increment the index
  if (curTs == prevTs) {
    index++;
  } else {
    // Otherwise, reset it
    index = 0;
  }
  // Save the timestamp
  prevTs = curTs;

  entryID = std::to_string(curTs);
  if (index > 0) {
    entryID += "_" + std::to_string(index);
  }
  return true;
}

inline static bool getTimestampFromID(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& entryID, uint64_t& timestamp, uint64_t& index) {
  if (entryID.empty()) {
    return false;
  }
  // Convert the unique ID back to a timestamp to find the entry
  std::string_view tsStr(entryID);

  auto underscorePos = tsStr.find('_');
  if (underscorePos != std::string_view::npos) {
    // Timestamp has an index
    tsStr.remove_suffix(tsStr.size() - underscorePos);
    std::string_view indexStr(entryID);
    indexStr.remove_prefix(underscorePos + 1);
    auto [ptr, ec] = std::from_chars(indexStr.data(),
                                     indexStr.data() + indexStr.size(), index);
    if (ec != std::errc()) {
      messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
      return false;
    }
  }
  // Timestamp has no index
  auto [ptr, ec] =
      std::from_chars(tsStr.data(), tsStr.data() + tsStr.size(), timestamp);
  if (ec != std::errc()) {
    messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
    return false;
  }
  return true;
}

inline log_entry::OriginatorTypes mapDbusOriginatorTypeToRedfish(
    const std::string& originatorType) {
  if (originatorType ==
      "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client") {
    return log_entry::OriginatorTypes::Client;
  }
  if (originatorType ==
      "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Internal") {
    return log_entry::OriginatorTypes::Internal;
  }
  if (originatorType ==
      "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes."
      "SupportingService") {
    return log_entry::OriginatorTypes::SupportingService;
  }
  return log_entry::OriginatorTypes::Invalid;
}

inline void parseDumpEntryFromDbusObject(
    const dbus::utility::ManagedObjectType::value_type& object,
    std::string& dumpStatus, uint64_t& size, uint64_t& timestampUs,
    std::string& originatorId, log_entry::OriginatorTypes& originatorType,
    std::string& entryType, std::string& primaryLogId,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  for (const auto& interfaceMap : object.second) {
    if (interfaceMap.first == "xyz.openbmc_project.Common.Progress") {
      for (const auto& propertyMap : interfaceMap.second) {
        if (propertyMap.first == "Status") {
          const auto* status = std::get_if<std::string>(&propertyMap.second);
          if (status == nullptr) {
            messages::internalError(asyncResp->res);
            break;
          }
          dumpStatus = *status;
        }
      }
    } else if (interfaceMap.first == "xyz.openbmc_project.Dump.Entry") {
      for (const auto& propertyMap : interfaceMap.second) {
        if (propertyMap.first == "Size") {
          const auto* sizePtr = std::get_if<uint64_t>(&propertyMap.second);
          if (sizePtr == nullptr) {
            messages::internalError(asyncResp->res);
            break;
          }
          size = *sizePtr;
          break;
        }
      }
    } else if (interfaceMap.first == "xyz.openbmc_project.Time.EpochTime") {
      for (const auto& propertyMap : interfaceMap.second) {
        if (propertyMap.first == "Elapsed") {
          const uint64_t* usecsTimeStamp =
              std::get_if<uint64_t>(&propertyMap.second);
          if (usecsTimeStamp == nullptr) {
            messages::internalError(asyncResp->res);
            break;
          }
          timestampUs = *usecsTimeStamp;
          break;
        }
      }
    } else if (interfaceMap.first ==
               "xyz.openbmc_project.Common.OriginatedBy") {
      for (const auto& propertyMap : interfaceMap.second) {
        if (propertyMap.first == "OriginatorId") {
          const std::string* id = std::get_if<std::string>(&propertyMap.second);
          if (id == nullptr) {
            messages::internalError(asyncResp->res);
            break;
          }
          originatorId = *id;
        }

        if (propertyMap.first == "OriginatorType") {
          const std::string* type =
              std::get_if<std::string>(&propertyMap.second);
          if (type == nullptr) {
            messages::internalError(asyncResp->res);
            break;
          }

          originatorType = mapDbusOriginatorTypeToRedfish(*type);
          if (originatorType == log_entry::OriginatorTypes::Invalid) {
            messages::internalError(asyncResp->res);
            break;
          }
        }
      }
    } else if (interfaceMap.first ==
               "xyz.openbmc_project.Dump.Entry.FaultLog") {
      for (const auto& propertyMap : interfaceMap.second) {
        if (propertyMap.first == "Type") {
          const std::string* entryTypePtr =
              std::get_if<std::string>(&propertyMap.second);
          if (entryTypePtr == nullptr) {
            messages::internalError(asyncResp->res);
            break;
          }
          if (*entryTypePtr ==
              "xyz.openbmc_project.Common.FaultLogType.FaultLogTypes."
              "Crashdump") {
            entryType = "Crashdump";
          } else if (*entryTypePtr ==
                     "xyz.openbmc_project.Common.FaultLogType.FaultLogTypes."
                     "CPER") {
            entryType = "CPER";
          }
        } else if (propertyMap.first == "PrimaryLogId") {
          const std::string* primaryLogIdPtr =
              std::get_if<std::string>(&propertyMap.second);
          if (primaryLogIdPtr == nullptr) {
            messages::internalError(asyncResp->res);
            break;
          }
          primaryLogId = *primaryLogIdPtr;
        }
      }
    }
  }
}

static std::string getDumpEntriesPath(const Dump& dump) {
  std::string entriesPath;

  switch (dump.type) {
    case DumpType::BMC_DUMP:
      entriesPath = "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/";
      break;
    case DumpType::BMC_FAULT_LOG:
      entriesPath = "/redfish/v1/Managers/bmc/LogServices/FaultLog/Entries/";
      break;
    case DumpType::SYSTEM_DUMP:
      entriesPath = "/redfish/v1/Systems/system/LogServices/Dump/Entries/";
      break;
    case DumpType::SYSTEM_FAULT_LOG:
      if (dump.systemName) {
        entriesPath = "/redfish/v1/Systems/" + *dump.systemName +
                      "/LogServices/FaultLog/Entries/";
      }
      break;
  }

  // Returns empty string on error
  return entriesPath;
}

constexpr std::array<std::pair<std::string_view, std::string_view>, 2>
    systemNameToDumpEntryPath{
        {{"system1", "/xyz/openbmc_project/dump/faultlog/0"},
         {"system2", "/xyz/openbmc_project/dump/faultlog/1"}}};

inline std::optional<std::string> getDumpEntryPathFromDump(const Dump& dump) {
  if (!dump.systemName || *dump.systemName == "system") {
    return "/xyz/openbmc_project/dump/" +
           std::string(
               boost::algorithm::to_lower_copy(dumpTypeToString(dump.type))) +
           "/entry/";
  }

  for (const auto& mapping : systemNameToDumpEntryPath) {
    if (mapping.first == *dump.systemName) {
      return std::string(mapping.second) + "/entry/";
    }
  }

  return std::nullopt;
}

// This function queries the collectionUri, and add the fields from the
// collectionUri to asyncResp. When the collectionUri response has less
// faultLog entries, the additional fields in asyncResp will be removed.
//
// This can happen during log rotation. We want to avoid incomplete
// data in asyncResp in the middle of log rotation.
void queryFaultCollection(
    App& app, const crow::Request& origReq,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& collectionUri,
    std::unordered_map<std::string, nlohmann::json::json_pointer>&
        faultLogEntries,
    nlohmann::json& originalMembers) {
  std::error_code ec;
  crow::Request newReq({boost::beast::http::verb::get, collectionUri, 11}, ec);

  if (ec) {
    messages::internalError(asyncResp->res);
    return;
  }

  newReq.with_trust_bundle = origReq.with_trust_bundle;
  newReq.peer_authenticated = origReq.peer_authenticated;
  newReq.peer_privileges = origReq.peer_privileges;
  newReq.fromGrpc = origReq.fromGrpc;

  auto newAsyncResp = std::make_shared<bmcweb::AsyncResp>(asyncResp->strand_);
  newAsyncResp->response_type = asyncResp->response_type;

  newAsyncResp->res.setCompleteRequestHandler(
      [faultLogEntries{std::move(faultLogEntries)},
       originalMembers(std::move(originalMembers)),
       asyncResp](const crow::Response& subResp) mutable {
        if (!subResp.jsonValue.contains("Members")) {
          BMCWEB_LOG_WARNING << "Sub query response is empty.";
          return;
        }
        for (const auto& resItem : subResp.jsonValue["Members"]) {
          const std::string link = resItem["@odata.id"];
          if (!faultLogEntries.contains(link)) {
            // This could happen when there is inconsistency in cache.
            // Ignoring this specific entry.
            BMCWEB_LOG_WARNING << "Entry doesn't exist in response: " << link;
            continue;
          }

          // This path is within "Members". Since it has been moved to a
          // separate jsonArray, it looks like '/0/Links/RelatedLogEntries/0'
          // here.
          const std::string& jsonPath = faultLogEntries.at(link).to_string();
          std::vector<std::string> split;
          bmcweb::split(split, jsonPath, '/');
          if (split.size() < 2) {
            BMCWEB_LOG_WARNING << "Invalid JSON path for entry " << link;
            continue;
          }
          unsigned int memberIdx =
              static_cast<unsigned int>(std::stoi(split[1]));
          originalMembers[faultLogEntries.at(link)] = resItem;
          asyncResp->res.jsonValue["Members"].push_back(
              std::move(originalMembers[""_json_pointer / memberIdx]));
        }

        asyncResp->res.jsonValue["Members@odata.count"] =
            asyncResp->res.jsonValue["Members"].size();

        asyncResp->res.eventSourceIds.insert(
            asyncResp->res.eventSourceIds.end(), subResp.eventSourceIds.begin(),
            subResp.eventSourceIds.end());
      });

  app.handle(newReq, newAsyncResp);
  redfish::query_param::propogateError(asyncResp->res, newAsyncResp->res);
}

inline bool shouldEfficientExpandFaultLog(DumpType dumpType,
                                          uint64_t delegatedExpandLevel) {
  // We only apply efficient expand when delegated expand level is 2+,
  // as log services are auto-expanded.
  // And only BMC_FAULT_LOG and SYSTEM_FAULT_LOG is supported.
  return (dumpType == DumpType::BMC_FAULT_LOG ||
          dumpType == DumpType::SYSTEM_FAULT_LOG) &&
         delegatedExpandLevel > 1;
}

void getDumpEntryCollection(App& app, const crow::Request& req,
                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                            const Dump& dump,
                            const query_param::Query& delegatedQuery) {
  std::string entriesPath = getDumpEntriesPath(dump);
  if (entriesPath.empty()) {
    messages::internalError(asyncResp->res);
    return;
  }

  uint64_t filterTimestampUs = 0;
  uint64_t delegatedExpandLevel = delegatedQuery.expandLevel;

  if (!delegatedQuery.filter.empty()) {
    std::vector<std::string> filterParams;
    bmcweb::split(filterParams, delegatedQuery.filter, ' ');

    // Only supported filter query is "Created ge '<timestamp>'"
    if (filterParams.size() != 3 || filterParams[0] != "Created" ||
        filterParams[1] != "ge") {
      redfish::messages::queryParameterValueFormatError(
          asyncResp->res, "$filter", delegatedQuery.filter);
      asyncResp->res.result(boost::beast::http::status::not_implemented);
      return;
    }

    std::string& timestampStr = filterParams[2];
    if (timestampStr.size() < 2 || timestampStr.at(0) != '\'' ||
        timestampStr.at(timestampStr.size() - 1) != '\'') {
      BMCWEB_LOG_ERROR << "Filter Timestamp not quoted " << timestampStr;
      redfish::messages::queryParameterValueFormatError(
          asyncResp->res, "$filter", delegatedQuery.filter);
      return;
    }
    std::optional<redfish::time_utils::usSinceEpoch> filterTimestampUsChrono =
        redfish::time_utils::dateStringToEpoch(
            timestampStr.substr(1, timestampStr.size() - 2));
    if (filterTimestampUsChrono == std::nullopt) {
      BMCWEB_LOG_ERROR << "Filter Timestamp validation failure"
                       << filterParams[2];
      redfish::messages::queryParameterValueFormatError(
          asyncResp->res, "$filter", delegatedQuery.filter);
      return;
    }
    filterTimestampUs = filterTimestampUsChrono->count();
  }

  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getManagedObjectsWithContext(
      "xyz.openbmc_project.Dump.Manager", {"/xyz/openbmc_project/dump"},
      context,
      // App's lifespan is tied with the program as it is created in the main
      // function
      [&app, asyncResp, entriesPath, dump, filterTimestampUs, req,
       delegatedExpandLevel](
          const boost::system::error_code& ec,
          const dbus::utility::ManagedObjectType& managedObjects) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DumpEntry resp_handler got error " << ec;
          messages::internalError(asyncResp->res);
          return;
        }

        // Remove ending slash
        std::string odataIdStr = entriesPath;
        if (!odataIdStr.empty()) {
          odataIdStr.pop_back();
        }

        asyncResp->res.jsonValue["@odata.type"] =
            "#LogEntryCollection.LogEntryCollection";
        asyncResp->res.jsonValue["@odata.id"] = std::move(odataIdStr);
        asyncResp->res.jsonValue["Name"] =
            dumpTypeToString(dump.type) + " Dump Entries";
        asyncResp->res.jsonValue["Description"] =
            "Collection of " + dumpTypeToString(dump.type) + " Dump Entries";

        nlohmann::json& entriesArray = asyncResp->res.jsonValue["Members"];
        entriesArray = nlohmann::json::array();
        std::optional<std::string> dumpEntryPath =
            getDumpEntryPathFromDump(dump);

        if (!dumpEntryPath) {
          BMCWEB_LOG_ERROR << "Cant convert system "
                           << dump.systemName.value_or("None")
                           << "to dumpEntryPath";
          messages::internalError(asyncResp->res);
          return;
        }

        dbus::utility::ManagedObjectType resp = managedObjects;
        std::sort(resp.begin(), resp.end(), [](const auto& l, const auto& r) {
          return AlphanumLess<std::string>()(l.first.filename(),
                                             r.first.filename());
        });

        // This maps the collection URI to all the entries and their json
        // pointer. This is used to fill in the entries in the final response.
        // Example:
        //  /redfish/v1/Systems/system1/LogServices/HostCper/Entries ->
        //    /redfish/v1/Systems/system1/LogServices/HostCper/Entries/1 ->
        //     /Members/Links/RelatedLogEntries/0
        std::unordered_map<
            std::string,
            std::unordered_map<std::string, nlohmann::json::json_pointer>>
            faultLogEntries;

        // This maps the collection URI to all the original members.
        // Example:
        //  /redfish/v1/Systems/system1/LogServices/HostCper/Entries ->
        //  [
        //        {
        //         "@odata.id": "../FaultLog/Entries/1",
        //        }
        //  ]
        std::unordered_map<std::string, nlohmann::json> faultLogOriginalMembers;

        for (auto& object : resp) {
          if (object.first.str.find(*dumpEntryPath) == std::string::npos) {
            continue;
          }
          uint64_t timestampUs = 0;
          uint64_t size = 0;
          std::string dumpStatus;
          std::string originatorId;
          std::string primaryLogId;
          std::string entryType;
          log_entry::OriginatorTypes originatorType =
              log_entry::OriginatorTypes::Internal;
          nlohmann::json::object_t thisEntry;

          std::string entryID = object.first.filename();
          if (entryID.empty()) {
            continue;
          }

          parseDumpEntryFromDbusObject(object, dumpStatus, size, timestampUs,
                                       originatorId, originatorType, entryType,
                                       primaryLogId, asyncResp);

          if (dumpStatus !=
                  "xyz.openbmc_project.Common.Progress.OperationStatus."
                  "Completed" &&
              !dumpStatus.empty()) {
            // Dump status is not Complete, no need to enumerate
            continue;
          }

          if (timestampUs < filterTimestampUs) {
            continue;
          }

          thisEntry["@odata.type"] = "#LogEntry.v1_11_0.LogEntry";
          thisEntry["@odata.id"] = entriesPath + entryID;
          thisEntry["Id"] = entryID;
          thisEntry["EntryType"] = "Event";
          thisEntry["Name"] = dumpTypeToString(dump.type) + " Dump Entry";
          thisEntry["Created"] =
              redfish::time_utils::getDateTimeUintUs(timestampUs);

          if (!originatorId.empty()) {
            thisEntry["Originator"] = originatorId;
            thisEntry["OriginatorType"] = originatorType;
          }

          if (dump.type == DumpType::BMC_DUMP) {
            thisEntry["DiagnosticDataType"] = "Manager";
            thisEntry["AdditionalDataURI"] =
                entriesPath + entryID + "/attachment";
            thisEntry["AdditionalDataSizeBytes"] = size;
          } else if (dump.type == DumpType::BMC_FAULT_LOG ||
                     dump.type == DumpType::SYSTEM_FAULT_LOG) {
            thisEntry["Created"] =
                redfish::time_utils::getDateTimeUintUs(timestampUs);
            thisEntry["DiagnosticDataType"] = "OEM";
            thisEntry["OEMDiagnosticDataType"] = "OpenBMC Fault Log";
            thisEntry["EntryType"] = "Oem";

            std::string systemPathSegment =
                dump.systemName ? *dump.systemName : "system";

            if (entryType == "CPER") {
              if (absl::StrContains(primaryLogId, "/Entries/")) {
                // This is for backward compatibility; we can remove it
                // later.
                thisEntry["AdditionalDataURI"] = crow::utility::urlFromPieces(
                    "redfish", "v1", "Systems", systemPathSegment,
                    "LogServices", primaryLogId);
              } else {
                // Will eventually be changed from AdditionalDataURI to
                // OriginOfCondition Link
                thisEntry["AdditionalDataURI"] =
#ifdef BMCWEB_ENABLE_CPER_CRASHDUMP_USE_FAULTLOG_ID
                    crow::utility::urlFromPieces(
                        "redfish", "v1", "Systems", systemPathSegment,
                        "LogServices", std::string(hostCperLogServiceName),
                        "Entries", entryID);
#else
                    crow::utility::urlFromPieces(
                        "redfish", "v1", "Systems", systemPathSegment,
                        "LogServices", std::string(hostCperLogServiceName),
                        "Entries", primaryLogId);
#endif
              }
              thisEntry["OemRecordFormat"] = "CPER";
            } else if (entryType == "Crashdump") {
              thisEntry["AdditionalDataURI"] =
#ifdef BMCWEB_ENABLE_CPER_CRASHDUMP_USE_FAULTLOG_ID
                  crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                               systemPathSegment, "LogServices",
                                               "Crashdump", "Entries", entryID);
#else
                  crow::utility::urlFromPieces(
                      "redfish", "v1", "Systems", systemPathSegment,
                      "LogServices", "Crashdump", "Entries", primaryLogId);
#endif
              thisEntry["OemRecordFormat"] = "Crashdump";
            } else {
              // entryType must be of CPER or CrashDump or else accessing
              // thisEntry["AdditionalDataURI"] becomes undefined behavior
              BMCWEB_LOG_ERROR << "entryType of faultLog is invalid";
              messages::internalError(asyncResp->res);
              return;
            }

            // Also export a RelatedLogEntry link to the AdditionalDataURI.
            thisEntry["Links"]["RelatedLogEntries"] = nlohmann::json::array();
            nlohmann::json::object_t relatedLogEntry;
            relatedLogEntry["@odata.id"] = thisEntry["AdditionalDataURI"];
            thisEntry["Links"]["RelatedLogEntries"].emplace_back(
                relatedLogEntry);
          } else if (dump.type == DumpType::SYSTEM_DUMP) {
            thisEntry["DiagnosticDataType"] = "OEM";
            thisEntry["OEMDiagnosticDataType"] = "System";
            thisEntry["AdditionalDataURI"] =
                entriesPath + entryID + "/attachment";
            thisEntry["AdditionalDataSizeBytes"] = size;
          }

          if (shouldEfficientExpandFaultLog(dump.type, delegatedExpandLevel)) {
            std::string dataUri = thisEntry["AdditionalDataURI"];
            std::string collectionUri =
                dataUri.substr(0, dataUri.rfind('/') + 1);
            if (!faultLogEntries.contains(collectionUri)) {
              faultLogEntries.emplace(
                  collectionUri,
                  std::unordered_map<std::string,
                                     nlohmann::json::json_pointer>());
              faultLogOriginalMembers.emplace(collectionUri,
                                              nlohmann::json::array());
            }
            auto jsonPath =
                ""_json_pointer /
                faultLogOriginalMembers[collectionUri].size() / "Links" /
                "RelatedLogEntries" /
                (thisEntry["Links"]["RelatedLogEntries"].size() - 1);
            faultLogEntries[collectionUri].emplace(dataUri, jsonPath);
            faultLogOriginalMembers[collectionUri].push_back(
                std::move(thisEntry));
          } else {
            entriesArray.push_back(std::move(thisEntry));
          }
        }
        asyncResp->res.jsonValue["Members@odata.count"] = entriesArray.size();

        if (shouldEfficientExpandFaultLog(dump.type, delegatedExpandLevel)) {
          // faultLogEntries and faultLogOriginamMemobers will be moved
          // into the completion handler of sub queries in
          // queryFaultCollection. It won't be availabe in this scope after
          // this loop.
          for (auto& [collectionUri, uriJsonPaths] : faultLogEntries) {
            nlohmann::json& originalMembers =
                faultLogOriginalMembers[collectionUri];
            queryFaultCollection(app, req, asyncResp, collectionUri,
                                 uriJsonPaths, originalMembers);
          }
        }
      });
}

inline void getDumpEntryById(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& entryID, const Dump& dump) {
  std::string entriesPath = getDumpEntriesPath(dump);
  if (entriesPath.empty()) {
    messages::internalError(asyncResp->res);
    return;
  }

  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getManagedObjectsWithContext(
      "xyz.openbmc_project.Dump.Manager", {"/xyz/openbmc_project/dump"},
      context,
      [asyncResp, entryID, dump, entriesPath](
          const boost::system::error_code& ec,
          const dbus::utility::ManagedObjectType& resp) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DumpEntry resp_handler got error " << ec;
          messages::internalError(asyncResp->res);
          return;
        }

        bool foundDumpEntry = false;
        std::optional<std::string> dumpEntryPath =
            getDumpEntryPathFromDump(dump);

        if (!dumpEntryPath) {
          BMCWEB_LOG_ERROR << "Cant convert system "
                           << dump.systemName.value_or("None")
                           << "to dumpEntryPath";
          messages::internalError(asyncResp->res);
          return;
        }

        for (const auto& objectPath : resp) {
          if (objectPath.first.str != *dumpEntryPath + entryID) {
            continue;
          }

          foundDumpEntry = true;
          uint64_t timestampUs = 0;
          uint64_t size = 0;
          std::string dumpStatus;
          std::string originatorId;
          std::string primaryLogId;
          std::string entryType;
          log_entry::OriginatorTypes originatorType =
              log_entry::OriginatorTypes::Internal;

          parseDumpEntryFromDbusObject(
              objectPath, dumpStatus, size, timestampUs, originatorId,
              originatorType, entryType, primaryLogId, asyncResp);

          if (dumpStatus !=
                  "xyz.openbmc_project.Common.Progress.OperationStatus."
                  "Completed" &&
              !dumpStatus.empty()) {
            // Dump status is not Complete
            // return not found until status is changed to Completed
            messages::resourceNotFound(
                asyncResp->res, dumpTypeToString(dump.type) + " dump", entryID);
            return;
          }

          asyncResp->res.jsonValue["@odata.type"] =
              "#LogEntry.v1_11_0.LogEntry";
          asyncResp->res.jsonValue["@odata.id"] = entriesPath + entryID;
          asyncResp->res.jsonValue["Id"] = entryID;
          asyncResp->res.jsonValue["EntryType"] = "Event";
          asyncResp->res.jsonValue["Name"] =
              dumpTypeToString(dump.type) + " Dump Entry";
          asyncResp->res.jsonValue["Created"] =
              redfish::time_utils::getDateTimeUintUs(timestampUs);

          if (!originatorId.empty()) {
            asyncResp->res.jsonValue["Originator"] = originatorId;
            asyncResp->res.jsonValue["OriginatorType"] = originatorType;
          }

          if (dump.type == DumpType::BMC_DUMP) {
            asyncResp->res.jsonValue["DiagnosticDataType"] = "Manager";
            asyncResp->res.jsonValue["AdditionalDataURI"] =
                entriesPath + entryID + "/attachment";
            asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
          } else if (dump.type == DumpType::BMC_FAULT_LOG ||
                     dump.type == DumpType::SYSTEM_FAULT_LOG) {
            asyncResp->res.jsonValue["Created"] =
                redfish::time_utils::getDateTimeUintUs(timestampUs);
            asyncResp->res.jsonValue["DiagnosticDataType"] = "OEM";
            asyncResp->res.jsonValue["OEMDiagnosticDataType"] =
                "OpenBMC Fault Log";
            asyncResp->res.jsonValue["EntryType"] = "Oem";

            std::string systemPathSegment =
                dump.systemName ? *dump.systemName : "system";

            if (entryType == "CPER") {
              if (absl::StrContains(primaryLogId, "/Entries/")) {
                // This is for backward compatibility; we can remove it
                // later.
                asyncResp->res.jsonValue["AdditionalDataURI"] =
                    crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                                 systemPathSegment,
                                                 "LogServices", primaryLogId);
              } else {
                // Will eventually be changed from AdditionalDataURI to
                // OriginOfCondition Link
                asyncResp->res.jsonValue["AdditionalDataURI"] =
#ifdef BMCWEB_ENABLE_CPER_CRASHDUMP_USE_FAULTLOG_ID
                    crow::utility::urlFromPieces(
                        "redfish", "v1", "Systems", systemPathSegment,
                        "LogServices", std::string(hostCperLogServiceName),
                        "Entries", entryID);
#else
                    crow::utility::urlFromPieces(
                        "redfish", "v1", "Systems", systemPathSegment,
                        "LogServices", std::string(hostCperLogServiceName),
                        "Entries", primaryLogId);
#endif
              }
              asyncResp->res.jsonValue["OemRecordFormat"] = "CPER";
            } else if (entryType == "Crashdump") {
              asyncResp->res.jsonValue["AdditionalDataURI"] =
#ifdef BMCWEB_ENABLE_CPER_CRASHDUMP_USE_FAULTLOG_ID
                  crow::utility::urlFromPieces("redfish", "v1", "Systems",
                                               systemPathSegment, "LogServices",
                                               "Crashdump", "Entries", entryID);
#else
                  crow::utility::urlFromPieces(
                      "redfish", "v1", "Systems", systemPathSegment,
                      "LogServices", "Crashdump", "Entries", primaryLogId);
#endif
              asyncResp->res.jsonValue["OemRecordFormat"] = "Crashdump";
            } else {
              // entryType must be of CPER or CrashDump or else accessing
              // thisEntry["AdditionalDataURI"] becomes undefined behavior
              BMCWEB_LOG_ERROR << "entryType of faultLog is invalid";
              messages::internalError(asyncResp->res);
              return;
            }

            // Also export a RelatedLogEntry link to the AdditionalDataURI.
            asyncResp->res.jsonValue["Links"]["RelatedLogEntries"] =
                nlohmann::json::array();
            nlohmann::json::object_t relatedLogEntry;
            relatedLogEntry["@odata.id"] =
                asyncResp->res.jsonValue["AdditionalDataURI"];
            asyncResp->res.jsonValue["Links"]["RelatedLogEntries"].emplace_back(
                relatedLogEntry);
          } else if (dump.type == DumpType::SYSTEM_DUMP) {
            asyncResp->res.jsonValue["DiagnosticDataType"] = "OEM";
            asyncResp->res.jsonValue["OEMDiagnosticDataType"] = "System";
            asyncResp->res.jsonValue["AdditionalDataURI"] =
                entriesPath + entryID + "/attachment";
            asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
          }
        }
        if (!foundDumpEntry) {
          BMCWEB_LOG_ERROR << "Can't find Dump Entry";
          messages::internalError(asyncResp->res);
          return;
        }
      });
}

inline void deleteDumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                            const std::string& entryID, const Dump& dump) {
  auto respHandler = [asyncResp, entryID](const boost::system::error_code& ec) {
    BMCWEB_LOG_DEBUG << "Dump Entry doDelete callback: Done";
    if (ec) {
      if (ec.value() == EBADR) {
        messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
        return;
      }
      BMCWEB_LOG_ERROR << "Dump (DBus) doDelete respHandler got error " << ec
                       << " entryID=" << entryID;
      messages::internalError(asyncResp->res);
      return;
    }
  };

  std::optional<std::string> dumpEntryPath = getDumpEntryPathFromDump(dump);

  if (!dumpEntryPath) {
    BMCWEB_LOG_ERROR << "Cant convert system "
                     << dump.systemName.value_or("None") << "to dumpEntryPath";
    messages::internalError(asyncResp->res);
    return;
  }

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_, respHandler, "xyz.openbmc_project.Dump.Manager",
      *dumpEntryPath + entryID, "xyz.openbmc_project.Object.Delete", "Delete");
}

constexpr const char* dumpsFolderBasePath =
    "/var/lib/phosphor-debug-collector/dumps";

inline bool getDumpFiles(crow::Response& resp, const std::string& dumpFilePath,
                         std::vector<std::filesystem::path>& dumpFiles) {
  std::error_code ec;
  std::filesystem::directory_iterator logPath(dumpFilePath, ec);
  if (ec) {
    BMCWEB_LOG_ERROR << ec.message();
    if (ec.value() == ENOENT) {
      // The directory didn't exist
      messages::resourceNotFound(resp, "", "");
    } else {
      messages::internalError(resp);
    }
    return false;
  }

  for (const std::filesystem::directory_entry& it : logPath) {
    std::string filename = it.path().filename();
    dumpFiles.emplace_back(it.path());
  }

  return true;
}

inline void downloadDumpEntry(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& entryID, const Dump& dump) {
  if (dump.type != DumpType::BMC_DUMP) {
    // We don't know for sure what resource was originally queried
    messages::resourceNotFound(asyncResp->res, "", "");
    return;
  }

  std::string dumpFolderPath = dumpsFolderBasePath;
  dumpFolderPath += "/" + entryID;
  std::vector<std::filesystem::path> dumpFiles;
  if (!getDumpFiles(asyncResp->res, dumpFolderPath, dumpFiles)) {
    // getDumpFiles() will have already written the error to the response
    BMCWEB_LOG_ERROR << "failed to get host log file path";
    return;
  }

  if (dumpFiles.size() != 1) {
    BMCWEB_LOG_ERROR << "Expected 1 dump file, found " << dumpFiles.size()
                     << " dump files";
    messages::internalError(asyncResp->res);
    return;
  }

  const std::string& dumpFile = dumpFiles.front().string();
  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
  int fd = open(dumpFile.c_str(), O_RDONLY);
  if (fd < 0) {
    BMCWEB_LOG_ERROR << "Failed to open dump file!";
    messages::internalError(asyncResp->res);
    return;
  }

  int64_t size = lseek(fd, 0, SEEK_END);
  if (size == -1) {
    messages::internalError(asyncResp->res);
    return;
  }

  // Arbitrary max size of 8MB
  constexpr int maxFileSize = 8 * 1024 * 1024;
  if (size > maxFileSize) {
    BMCWEB_LOG_ERROR << "File size " << size
                     << " exceeds maximum allowed size of " << maxFileSize;
    messages::internalError(asyncResp->res);
  }
  std::vector<char> data(static_cast<size_t>(size));
  int64_t rc = lseek(fd, 0, SEEK_SET);
  if (rc == -1) {
    messages::internalError(asyncResp->res);
    return;
  }
  rc = read(fd, data.data(), data.size());
  if ((rc == -1) || (rc != size)) {
    messages::internalError(asyncResp->res);
    return;
  }
  close(fd);

  std::string_view strData(data.data(), data.size());
  std::string output(strData);
  asyncResp->res.addHeader(boost::beast::http::field::content_type,
                           "application/octet-stream");
  asyncResp->res.body() = std::move(output);
}

inline DumpCreationProgress mapDbusStatusToDumpProgress(
    const std::string& status) {
  if (status == "xyz.openbmc_project.Common.Progress.OperationStatus.Failed" ||
      status == "xyz.openbmc_project.Common.Progress.OperationStatus.Aborted") {
    return DumpCreationProgress::DUMP_CREATE_FAILED;
  }
  if (status ==
      "xyz.openbmc_project.Common.Progress.OperationStatus.Completed") {
    return DumpCreationProgress::DUMP_CREATE_SUCCESS;
  }
  return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
}

inline DumpCreationProgress getDumpCompletionStatus(
    const dbus::utility::DBusPropertiesMap& values) {
  for (const auto& [key, val] : values) {
    if (key == "Status") {
      const std::string* value = std::get_if<std::string>(&val);
      if (value == nullptr) {
        BMCWEB_LOG_ERROR << "Status property value is null";
        return DumpCreationProgress::DUMP_CREATE_FAILED;
      }
      return mapDbusStatusToDumpProgress(*value);
    }
  }
  return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
}

inline std::string getDumpEntryPath(const std::string& dumpPath) {
  if (dumpPath == "/xyz/openbmc_project/dump/bmc/entry") {
    return "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/";
  }
  if (dumpPath == "/xyz/openbmc_project/dump/system/entry") {
    return "/redfish/v1/Systems/system/LogServices/Dump/Entries/";
  }
  return "";
}

inline void createDumpTaskCallback(
    task::Payload&& payload,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const sdbusplus::message::object_path& createdObjPath) {
  const std::string dumpPath = createdObjPath.parent_path().str;
  const std::string dumpId = createdObjPath.filename();

  std::string dumpEntryPath = getDumpEntryPath(dumpPath);

  if (dumpEntryPath.empty()) {
    BMCWEB_LOG_ERROR << "Invalid dump type received";
    messages::internalError(asyncResp->res);
    return;
  }

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp, payload, createdObjPath,
       dumpEntryPath{std::move(dumpEntryPath)},
       dumpId](const boost::system::error_code& ec,
               const std::string& introspectXml) {
        if (ec) {
          BMCWEB_LOG_ERROR << "Introspect call failed with error: "
                           << ec.message();
          messages::internalError(asyncResp->res);
          return;
        }

        // Check if the created dump object has implemented Progress
        // interface to track dump completion. If yes, fetch the "Status"
        // property of the interface, modify the task state accordingly.
        // Else, return task completed.
        tinyxml2::XMLDocument doc;

        doc.Parse(introspectXml.data(), introspectXml.size());
        tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
        if (pRoot == nullptr) {
          BMCWEB_LOG_ERROR << "XML document failed to parse";
          messages::internalError(asyncResp->res);
          return;
        }
        tinyxml2::XMLElement* interfaceNode =
            pRoot->FirstChildElement("interface");

        bool isProgressIntfPresent = false;
        while (interfaceNode != nullptr) {
          const char* thisInterfaceName = interfaceNode->Attribute("name");
          if (thisInterfaceName != nullptr) {
            if (thisInterfaceName ==
                std::string_view("xyz.openbmc_project.Common.Progress")) {
              interfaceNode = interfaceNode->NextSiblingElement("interface");
              continue;
            }
            isProgressIntfPresent = true;
            break;
          }
          interfaceNode = interfaceNode->NextSiblingElement("interface");
        }

        std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
            [createdObjPath, dumpEntryPath, dumpId, isProgressIntfPresent](
                const boost::system::error_code& err, sdbusplus::message_t& msg,
                const std::shared_ptr<task::TaskData>& taskData) {
              if (err) {
                BMCWEB_LOG_ERROR << createdObjPath.str
                                 << ": Error in creating dump";
                taskData->messages.emplace_back(messages::internalError());
                taskData->state = "Cancelled";
                return task::completed;
              }

              if (isProgressIntfPresent) {
                dbus::utility::DBusPropertiesMap values;
                std::string prop;
                msg.read(prop, values);

                DumpCreationProgress dumpStatus =
                    getDumpCompletionStatus(values);
                if (dumpStatus == DumpCreationProgress::DUMP_CREATE_FAILED) {
                  BMCWEB_LOG_ERROR << createdObjPath.str
                                   << ": Error in creating dump";
                  taskData->state = "Cancelled";
                  return task::completed;
                }

                if (dumpStatus ==
                    DumpCreationProgress::DUMP_CREATE_INPROGRESS) {
                  BMCWEB_LOG_DEBUG << createdObjPath.str
                                   << ": Dump creation task is in progress";
                  return !task::completed;
                }
              }

              nlohmann::json retMessage = messages::success();
              taskData->messages.emplace_back(retMessage);

              std::string headerLoc = "Location: " + dumpEntryPath +
                                      http_helpers::urlEncode(dumpId);
              taskData->payload->httpHeaders.emplace_back(std::move(headerLoc));

              BMCWEB_LOG_DEBUG << createdObjPath.str
                               << ": Dump creation task completed";
              taskData->state = "Completed";
              return task::completed;
            },
            "type='signal',interface='org.freedesktop.DBus.Properties',"
            "member='PropertiesChanged',path='" +
                createdObjPath.str + "'");

        // The task timer is set to max time limit within which the
        // requested dump will be collected.
        task->startTimer(std::chrono::minutes(6));
        task->populateResp(asyncResp->res);
        task->payload.emplace(payload);
      },
      "xyz.openbmc_project.Dump.Manager", createdObjPath,
      "org.freedesktop.DBus.Introspectable", "Introspect");
}

inline void createDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const crow::Request& req, const Dump& dump) {
  std::string dumpPath = getDumpEntriesPath(dump);
  if (dumpPath.empty()) {
    messages::internalError(asyncResp->res);
    return;
  }

  std::optional<std::string> diagnosticDataType;
  std::optional<std::string> oemDiagnosticDataType;

  if (!redfish::json_util::readJsonAction(
          req, asyncResp->res, "DiagnosticDataType", diagnosticDataType,
          "OEMDiagnosticDataType", oemDiagnosticDataType)) {
    return;
  }

  if (dump.type == DumpType::SYSTEM_DUMP) {
    if (!oemDiagnosticDataType || !diagnosticDataType) {
      BMCWEB_LOG_ERROR
          << "CreateDump action parameter "
             "'DiagnosticDataType'/'OEMDiagnosticDataType' value not found!";
      messages::actionParameterMissing(
          asyncResp->res, "CollectDiagnosticData",
          "DiagnosticDataType & OEMDiagnosticDataType");
      return;
    }
    if ((*oemDiagnosticDataType != "System") ||
        (*diagnosticDataType != "OEM")) {
      BMCWEB_LOG_ERROR << "Wrong parameter values passed";
      messages::internalError(asyncResp->res);
      return;
    }
    dumpPath = "/redfish/v1/Systems/system/LogServices/Dump/";
  } else if (dump.type == DumpType::BMC_DUMP) {
    if (!diagnosticDataType) {
      BMCWEB_LOG_ERROR
          << "CreateDump action parameter 'DiagnosticDataType' not found!";
      messages::actionParameterMissing(asyncResp->res, "CollectDiagnosticData",
                                       "DiagnosticDataType");
      return;
    }
    if (*diagnosticDataType != "Manager") {
      BMCWEB_LOG_ERROR
          << "Wrong parameter value passed for 'DiagnosticDataType'";
      messages::internalError(asyncResp->res);
      return;
    }
    dumpPath = "/redfish/v1/Managers/bmc/LogServices/Dump/";
  } else {
    BMCWEB_LOG_ERROR << "CreateDump failed. Unknown dump type";
    messages::internalError(asyncResp->res);
    return;
  }

  std::vector<std::pair<std::string, std::variant<std::string, uint64_t>>>
      createDumpParamVec;

  if (req.session != nullptr) {
    createDumpParamVec.emplace_back(
        "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorId",
        req.session->clientIp);
    createDumpParamVec.emplace_back(
        "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorType",
        "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client");
  }

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp, payload(task::Payload(req)), dumpPath](
          const boost::system::error_code& ec, const sdbusplus::message_t& msg,
          const sdbusplus::message::object_path& objPath) mutable {
        if (ec) {
          BMCWEB_LOG_ERROR << "CreateDump resp_handler got error " << ec;
          const sd_bus_error* dbusError = msg.get_error();
          if (dbusError == nullptr) {
            messages::internalError(asyncResp->res);
            return;
          }

          BMCWEB_LOG_ERROR << "CreateDump DBus error: " << dbusError->name
                           << " and error msg: " << dbusError->message;
          if (std::string_view("xyz.openbmc_project.Common.Error.NotAllowed") ==
              dbusError->name) {
            messages::resourceInStandby(asyncResp->res);
            return;
          }
          if (std::string_view(
                  "xyz.openbmc_project.Dump.Create.Error.Disabled") ==
              dbusError->name) {
            messages::serviceDisabled(asyncResp->res, dumpPath);
            return;
          }
          if (std::string_view(
                  "xyz.openbmc_project.Common.Error.Unavailable") ==
              dbusError->name) {
            messages::resourceInUse(asyncResp->res);
            return;
          }
          // Other Dbus errors such as:
          // xyz.openbmc_project.Common.Error.InvalidArgument &
          // org.freedesktop.DBus.Error.InvalidArgs are all related to
          // the dbus call that is made here in the bmcweb
          // implementation and has nothing to do with the client's
          // input in the request. Hence, returning internal error
          // back to the client.
          messages::internalError(asyncResp->res);
          return;
        }
        BMCWEB_LOG_DEBUG << "Dump Created. Path: " << objPath.str;
        createDumpTaskCallback(std::move(payload), asyncResp, objPath);
      },
      "xyz.openbmc_project.Dump.Manager",
      "/xyz/openbmc_project/dump/" +
          std::string(
              boost::algorithm::to_lower_copy(dumpTypeToString(dump.type))),
      "xyz.openbmc_project.Dump.Create", "CreateDump", createDumpParamVec);
}

inline std::optional<std::string> getDumpManagerCollectionPath(
    const Dump& dump) {
  if (!dump.systemName || *dump.systemName == "system") {
    return "/xyz/openbmc_project/dump/" +
           std::string(
               boost::algorithm::to_lower_copy(dumpTypeToString(dump.type)));
  }

  for (const auto& mapping : systemNameToDumpEntryPath) {
    if (mapping.first == *dump.systemName) {
      return std::string(mapping.second);
    }
  }

  return std::nullopt;
}

inline void clearDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                      const Dump& dump) {
  std::optional<std::string> dumpManagerCollectionPath =
      getDumpManagerCollectionPath(dump);

  if (!dumpManagerCollectionPath) {
    BMCWEB_LOG_ERROR << "Cant get dumpManagerCollectionPath from system "
                     << dump.systemName.value_or("none");
    messages::internalError(asyncResp->res);
    return;
  }

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp](const boost::system::error_code& ec) {
        if (ec) {
          BMCWEB_LOG_ERROR << "clearDump resp_handler got error " << ec;
          messages::internalError(asyncResp->res);
          return;
        }
      },
      "xyz.openbmc_project.Dump.Manager", *dumpManagerCollectionPath,
      "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
}

inline static void parseCrashdumpParameters(
    const dbus::utility::DBusPropertiesMap& params, std::string& filename,
    std::string& timestamp, std::string& logfile) {
  const std::string* filenamePtr = nullptr;
  const std::string* timestampPtr = nullptr;
  const std::string* logfilePtr = nullptr;

  const bool success = sdbusplus::unpackPropertiesNoThrow(
      dbus_utils::UnpackErrorPrinter(), params, "Timestamp", timestampPtr,
      "Filename", filenamePtr, "Log", logfilePtr);

  if (!success) {
    return;
  }

  if (filenamePtr != nullptr) {
    filename = *filenamePtr;
  }

  if (timestampPtr != nullptr) {
    timestamp = *timestampPtr;
  }

  if (logfilePtr != nullptr) {
    logfile = *logfilePtr;
  }
}

inline void handleLogServices(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemPath) {
  // If the systemPath is empty, then the system is single host
  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();
  }

  // Collections don't include the static data added by SubRoute
  // because it has a duplicate entry for members
  asyncResp->res.jsonValue["@odata.type"] =
      "#LogServiceCollection.LogServiceCollection";
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/" + systemName + "/LogServices";
  asyncResp->res.jsonValue["Name"] = "System Log Services Collection";
  asyncResp->res.jsonValue["Description"] =
      "Collection of LogServices for this Computer System";

  nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"];
  logServiceArray = nlohmann::json::array();

#ifdef BMCWEB_ENABLE_REDFISH_HOST_LOGGER
  nlohmann::json::object_t hostlogger;
  hostlogger["@odata.id"] =
      "/redfish/v1/Systems/" + systemName + "/LogServices/HostLogger";
  logServiceArray.push_back(std::move(hostlogger));
#endif

#ifdef BMCWEB_ENABLE_REDFISH_SYSTEM_FAULT_LOG
  nlohmann::json::object_t faultLog;
  faultLog["@odata.id"] =
      "/redfish/v1/Systems/" + systemName + "/LogServices/FaultLog";
  logServiceArray.push_back(std::move(faultLog));
#endif

  // Similar to the structure of the ComputerSystem Handlers, we will separate
  // multi-host features and singlehost features.
  if (!multiHost) {
#ifdef BMCWEB_ENABLE_REDFISH_EVENT_LOG
    nlohmann::json::object_t eventLog;
    eventLog["@odata.id"] = "/redfish/v1/Systems/system/LogServices/EventLog";
    logServiceArray.push_back(std::move(eventLog));
#endif

#ifdef BMCWEB_ENABLE_RASMANAGER_EVENT_LOG
    nlohmann::json::object_t rasManagerLog;
    rasManagerLog["@odata.id"] =
        "/redfish/v1/Systems/system/LogServices/HostCper";
    logServiceArray.push_back(std::move(rasManagerLog));
#endif

#ifdef BMCWEB_ENABLE_REDFISH_DUMP_LOG
    nlohmann::json::object_t dumpLog;
    dumpLog["@odata.id"] = "/redfish/v1/Systems/system/LogServices/Dump";
    logServiceArray.push_back(std::move(dumpLog));
#endif

#ifdef BMCWEB_ENABLE_REDFISH_CPU_LOG
    nlohmann::json::object_t crashdump;
    crashdump["@odata.id"] = "/redfish/v1/Systems/system/LogServices/Crashdump";
    logServiceArray.push_back(std::move(crashdump));
#endif

#ifdef BMCWEB_ENABLE_PPR
    nlohmann::json::object_t ppr;
    ppr["@odata.id"] =
        "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair";
    logServiceArray.push_back(std::move(ppr));
#endif

#ifdef BMCWEB_ENABLE_REDFISH_EXTERNAL_STORER
    // This is the ExternalStorer integration point
    for (const auto& instance :
         external_storer::rememberLogServices()->listInstances()) {
      nlohmann::json::object_t externalStorerInstance;
      externalStorerInstance["@odata.id"] =
          "/redfish/v1/Systems/system/LogServices/" + instance;
      logServiceArray.push_back(std::move(externalStorerInstance));
    }
#endif

#ifdef BMCWEB_ENABLE_REDFISH_BOOT_TIME_LOG
    nlohmann::json::object_t bootTime;
    bootTime["@odata.id"] =
        "/redfish/v1/Systems/" + systemName + "/LogServices/BootTime";
    logServiceArray.push_back(std::move(bootTime));
#endif
    constexpr std::array<std::string_view, 1> interfaces = {
        "xyz.openbmc_project.State.Boot.PostCode"};
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTreePaths(
        "/", 0, interfaces, requestContext,
        [asyncResp](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreePathsResponse& subtreePath) {
          if (ec) {
            BMCWEB_LOG_ERROR << ec;
            return;
          }

          for (const auto& pathStr : subtreePath) {
            if (absl::StrContains(pathStr, "PostCode")) {
              nlohmann::json& logServiceArrayLocal =
                  asyncResp->res.jsonValue["Members"];
              nlohmann::json::object_t member;
              member["@odata.id"] =
                  "/redfish/v1/Systems/system/LogServices/PostCodes";

              logServiceArrayLocal.push_back(std::move(member));

              asyncResp->res.jsonValue["Members@odata.count"] =
                  logServiceArrayLocal.size();
              return;
            }
          }
        });
  }
  asyncResp->res.jsonValue["Members@odata.count"] = logServiceArray.size();
}

void requestRoutesSystemLogServiceCollection(App& app) {
  /**
   * Functions triggers appropriate requests on DBus
   */
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/")
      .privileges(redfish::privileges::getLogServiceCollection)
      .methods(boost::beast::http::verb::get)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& systemName) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }

            redfish::system_utils::getSystemInformation(asyncResp, systemName,
                                                        handleLogServices);
          });
}

constexpr const char* hostLoggerFolderPath = "/var/log/console";

// Hardcoding mapping of system1 -> S2 and system2 -> S1
constexpr std::array<std::pair<std::string_view, std::string_view>, 2>
    systemNameToLogPrefix{{{"system1", "S2"}, {"system2", "S1"}}};

inline bool getHostLoggerFiles(
    const std::string& hostLoggerFilePath,
    std::vector<std::filesystem::path>& hostLoggerFiles,
    const std::string& systemName, bool multiHost) {
  std::error_code ec;
  std::filesystem::directory_iterator logPath(hostLoggerFilePath, ec);
  if (ec) {
    BMCWEB_LOG_ERROR << ec.message();
    return false;
  }

  // Setting default filePrefix is log
  std::string filePrefix = defaultLogPrefix;

  // For multi-host systems, the prefix will change based on which host
  if (multiHost) {
    // Right now we dont have a guarateed and extendable way to determine
    // which file is for which host. Will hardcode for now and fix later
    bool systemFound = false;
    for (const auto& mapping : systemNameToLogPrefix) {
      if (mapping.first == systemName) {
        filePrefix += mapping.second;
        systemFound = true;
        break;
      }
    }

    if (!systemFound) {
      BMCWEB_LOG_ERROR << "Could not find HostLogPrefix for system "
                       << systemName;
      return false;
    }
  }

  for (const std::filesystem::directory_entry& it : logPath) {
    std::string filename = it.path().filename();
    // Prefix of each log files is "log". Find the file and save the
    // path
    if (filename.starts_with(filePrefix)) {
      hostLoggerFiles.emplace_back(it.path());
    }
  }
  // As the log files rotate, they are appended with a ".#" that is higher for
  // the older logs. Since we start from oldest logs, sort the name in
  // descending order.
  std::sort(hostLoggerFiles.rbegin(), hostLoggerFiles.rend(),
            AlphanumLess<std::string>());

  return true;
}

inline bool getHostLoggerEntries(
    const std::vector<std::filesystem::path>& hostLoggerFiles, uint64_t skip,
    uint64_t top, std::vector<std::string>& logEntries, size_t& logCount) {
  GzFileReader logFile;

  // Go though all log files and expose host logs.
  for (const std::filesystem::path& it : hostLoggerFiles) {
    if (!logFile.gzGetLines(it.string(), skip, top, logEntries, logCount)) {
      BMCWEB_LOG_ERROR << "fail to expose host logs";
      return false;
    }
  }
  // Get lastMessage from constructor by getter
  std::string lastMessage = logFile.getLastMessage();
  if (!lastMessage.empty()) {
    logCount++;
    if (logCount > skip && logCount <= (skip + top)) {
      logEntries.push_back(lastMessage);
    }
  }
  return true;
}

inline void fillHostLoggerEntryJson(const std::string& logEntryID,
                                    const std::string& msg,
                                    nlohmann::json::object_t& logEntryJson,
                                    const std::string& systemName) {
  // Fill in the log entry with the gathered data.
  logEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
  logEntryJson["@odata.id"] = crow::utility::urlFromPieces(
      "redfish", "v1", "Systems", systemName, "LogServices", "HostLogger",
      "Entries", logEntryID);
  logEntryJson["Name"] = "Host Logger Entry";
  logEntryJson["Id"] = logEntryID;
  logEntryJson["Message"] = msg;
  logEntryJson["EntryType"] = "Oem";
  logEntryJson["Severity"] = "OK";
  logEntryJson["OemRecordFormat"] = "Host Logger Entry";
}

inline void handleSystemHostLogger(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemPath) {
  // Default systemName is system and change if system is multi-host
  std::string systemName = "system";
  if (!systemPath.empty()) {
    systemName = sdbusplus::message::object_path(systemPath).filename();
  }

  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/" + systemName + "/LogServices/HostLogger";
  asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_1_0.LogService";
  asyncResp->res.jsonValue["Name"] = "Host Logger Service";
  asyncResp->res.jsonValue["Description"] = "Host Logger Service";
  asyncResp->res.jsonValue["Id"] = "HostLogger";
  asyncResp->res.jsonValue["Entries"]["@odata.id"] =
      "/redfish/v1/Systems/" + systemName + "/LogServices/HostLogger/Entries";
}

void requestRoutesSystemHostLogger(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/")
      .privileges(redfish::privileges::getLogService)
      .methods(boost::beast::http::verb::get)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& systemName) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }
            redfish::system_utils::getSystemInformation(asyncResp, systemName,
                                                        handleSystemHostLogger);
          });
}

inline void handleSystemHostLoggerCollection(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemPath, const query_param::Query& delegatedQuery) {
  // If the systemPath is empty, then the system is single host
  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();
  }

  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/" + systemName + "/LogServices/HostLogger/Entries";
  asyncResp->res.jsonValue["@odata.type"] =
      "#LogEntryCollection.LogEntryCollection";
  asyncResp->res.jsonValue["Name"] = "HostLogger Entries";
  asyncResp->res.jsonValue["Description"] = "Collection of HostLogger Entries";
  nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
  logEntryArray = nlohmann::json::array();
  asyncResp->res.jsonValue["Members@odata.count"] = 0;

  std::vector<std::filesystem::path> hostLoggerFiles;
  if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles, systemName,
                          multiHost)) {
    BMCWEB_LOG_ERROR << "fail to get host log file path";
    return;
  }
  // If we weren't provided top and skip limits, use the defaults.
  size_t skip = delegatedQuery.skip.value_or(0);
  size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);
  size_t logCount = 0;
  // This vector only store the entries we want to expose that
  // control by skip and top.
  std::vector<std::string> logEntries;
  if (!getHostLoggerEntries(hostLoggerFiles, skip, top, logEntries, logCount)) {
    messages::internalError(asyncResp->res);
    return;
  }
  // If vector is empty, that means skip value larger than total
  // log count
  if (logEntries.empty()) {
    asyncResp->res.jsonValue["Members@odata.count"] = logCount;
    return;
  }
  if (!logEntries.empty()) {
    for (size_t i = 0; i < logEntries.size(); i++) {
      nlohmann::json::object_t hostLogEntry;
      fillHostLoggerEntryJson(std::to_string(skip + i), logEntries[i],
                              hostLogEntry, systemName);
      logEntryArray.push_back(std::move(hostLogEntry));
    }

    asyncResp->res.jsonValue["Members@odata.count"] = logCount;
    if (skip + top < logCount) {
      asyncResp->res.jsonValue["Members@odata.nextLink"] =
          "/redfish/v1/Systems/" + systemName +
          "/LogServices/HostLogger/Entries?$skip=" + std::to_string(skip + top);
    }
  }
}

inline void handleGetSystemHostLoggerCollection(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  query_param::QueryCapabilities capabilities = {
      .canDelegateTop = true,
      .canDelegateSkip = true,
  };
  query_param::Query delegatedQuery;
  if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
                                                delegatedQuery, capabilities)) {
    return;
  }
  redfish::system_utils::getSystemInformation(
      asyncResp, systemName,
      [delegatedQuery](const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                       const std::string& systemPath) {
        handleSystemHostLoggerCollection(aResp, systemPath, delegatedQuery);
      });
}

void requestRoutesSystemHostLoggerCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/Entries/")
      .privileges(redfish::privileges::getLogEntry)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetSystemHostLoggerCollection, std::ref(app)));
}

inline void handleSystemHostLoggerLogEntry(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemPath, const std::string& param) {
  // If the systemPath is empty, then the system is single host
  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();
  }

  const std::string& targetID = param;

  uint64_t idInt = 0;

  // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  const char* end = targetID.data() + targetID.size();

  auto [ptr, ec] = std::from_chars(targetID.data(), end, idInt);
  if (ec == std::errc::invalid_argument ||
      ec == std::errc::result_out_of_range) {
    messages::resourceNotFound(asyncResp->res, "LogEntry", param);
    return;
  }

  std::vector<std::filesystem::path> hostLoggerFiles;
  if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles, systemName,
                          multiHost)) {
    BMCWEB_LOG_ERROR << "fail to get host log file path";
    return;
  }

  size_t logCount = 0;
  size_t top = 1;
  std::vector<std::string> logEntries;
  // We can get specific entry by skip and top. For example, if we
  // want to get nth entry, we can set skip = n-1 and top = 1 to
  // get that entry
  if (!getHostLoggerEntries(hostLoggerFiles, idInt, top, logEntries,
                            logCount)) {
    messages::internalError(asyncResp->res);
    return;
  }

  if (!logEntries.empty()) {
    nlohmann::json::object_t hostLogEntry;
    fillHostLoggerEntryJson(targetID, logEntries[0], hostLogEntry, systemName);
    asyncResp->res.jsonValue.update(hostLogEntry);
    return;
  }

  // Requested ID was not found
  messages::resourceNotFound(asyncResp->res, "LogEntry", param);
}

inline void handleGetSystemHostLoggerLogEntry(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& param) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  redfish::system_utils::getSystemInformation(
      asyncResp, systemName,
      [param](const std::shared_ptr<bmcweb::AsyncResp>& aResp,
              const std::string& systemPath) {
        handleSystemHostLoggerLogEntry(aResp, systemPath, param);
      });
}

void requestRoutesSystemHostLoggerLogEntry(App& app) {
  BMCWEB_ROUTE(
      app, "/redfish/v1/Systems/<str>/LogServices/HostLogger/Entries/<str>/")
      .privileges(redfish::privileges::getLogEntry)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetSystemHostLoggerLogEntry, std::ref(app)));
}

inline void handleBMCLogServicesCollectionGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  // Collections don't include the static data added by SubRoute
  // because it has a duplicate entry for members
  asyncResp->res.jsonValue["@odata.type"] =
      "#LogServiceCollection.LogServiceCollection";
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Managers/bmc/LogServices";
  asyncResp->res.jsonValue["Name"] = "Open BMC Log Services Collection";
  asyncResp->res.jsonValue["Description"] =
      "Collection of LogServices for this Manager";
  nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"];
  logServiceArray = nlohmann::json::array();

#ifdef BMCWEB_ENABLE_REDFISH_BMC_JOURNAL
  nlohmann::json::object_t journal;
  journal["@odata.id"] = "/redfish/v1/Managers/bmc/LogServices/Journal";
  logServiceArray.push_back(std::move(journal));
#endif

#ifdef BMCWEB_ENABLE_REDFISH_BOOT_TIME_LOG
  nlohmann::json::object_t bootTime;
  bootTime["@odata.id"] = "/redfish/v1/Managers/bmc/LogServices/BootTime";
  logServiceArray.push_back(std::move(bootTime));
#endif

  asyncResp->res.jsonValue["Members@odata.count"] = logServiceArray.size();

#ifdef BMCWEB_ENABLE_REDFISH_DUMP_LOG
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Collection.DeleteAll"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/xyz/openbmc_project/dump", 0, interfaces, requestContext,
      [asyncResp](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreePathsResponse& subTreePaths) {
        if (ec) {
          BMCWEB_LOG_ERROR
              << "handleBMCLogServicesCollectionGet respHandler got error "
              << ec;
          // Assume that getting an error simply means there are no dump
          // LogServices. Return without adding any error response.
          return;
        }

        nlohmann::json& logServiceArrayLocal =
            asyncResp->res.jsonValue["Members"];

        for (const std::string& path : subTreePaths) {
          if (path == "/xyz/openbmc_project/dump/bmc") {
            nlohmann::json::object_t member;
            member["@odata.id"] = "/redfish/v1/Managers/bmc/LogServices/Dump";
            logServiceArrayLocal.push_back(std::move(member));
          } else if (path == "/xyz/openbmc_project/dump/faultlog") {
            nlohmann::json::object_t member;
            member["@odata.id"] =
                "/redfish/v1/Managers/bmc/LogServices/FaultLog";
            logServiceArrayLocal.push_back(std::move(member));
          }
        }

        asyncResp->res.jsonValue["Members@odata.count"] =
            logServiceArrayLocal.size();
      });
#endif
}

void requestRoutesBMCLogServiceCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/")
      .privileges(redfish::privileges::getLogServiceCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleBMCLogServicesCollectionGet, std::ref(app)));
}

inline void handleGetBMCJournalLogService(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_1_0.LogService";
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Managers/bmc/LogServices/Journal";
  asyncResp->res.jsonValue["Name"] = "Open BMC Journal Log Service";
  asyncResp->res.jsonValue["Description"] = "BMC Journal Log Service";
  asyncResp->res.jsonValue["Id"] = "Journal";
  asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";

  std::pair<std::string, std::string> redfishDateTimeOffset =
      redfish::time_utils::getDateTimeOffsetNow();
  asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
  asyncResp->res.jsonValue["DateTimeLocalOffset"] =
      redfishDateTimeOffset.second;

  asyncResp->res.jsonValue["Entries"]["@odata.id"] =
      "/redfish/v1/Managers/bmc/LogServices/Journal/Entries";
}

void requestRoutesBMCJournalLogService(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Journal/")
      .privileges(redfish::privileges::getLogService)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetBMCJournalLogService, std::ref(app)));
}

static int fillBMCJournalLogEntryJson(
    const std::string& bmcJournalLogEntryID, sd_journal* journal,
    nlohmann::json::object_t& bmcJournalLogEntryJson) {
  // Get the Log Entry contents
  int ret = 0;

  std::string message;
  std::string_view syslogID;
  ret = getJournalMetadata(journal, "SYSLOG_IDENTIFIER", syslogID);
  if (ret < 0) {
    BMCWEB_LOG_ERROR << "Failed to read SYSLOG_IDENTIFIER field: "
                     << strerror(-ret);
  }
  if (!syslogID.empty()) {
    message += std::string(syslogID) + ": ";
  }

  std::string_view msg;
  ret = getJournalMetadata(journal, "MESSAGE", msg);
  if (ret < 0) {
    BMCWEB_LOG_ERROR << "Failed to read MESSAGE field: " << strerror(-ret);
    return 1;
  }
  message += std::string(msg);

  // Get the severity from the PRIORITY field
  int64_t severity = 8;  // Default to an invalid priority
  ret = getJournalMetadataToInt64(journal, "PRIORITY", severity);
  if (ret < 0) {
    BMCWEB_LOG_ERROR << "Failed to read PRIORITY field: " << strerror(-ret);
  }

  // Get the Created time from the timestamp
  std::string entryTimeStr;
  if (!getEntryTimestamp(journal, entryTimeStr)) {
    return 1;
  }

  // Fill in the log entry with the gathered data
  bmcJournalLogEntryJson["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
  bmcJournalLogEntryJson["@odata.id"] = crow::utility::urlFromPieces(
      "redfish", "v1", "Managers", "bmc", "LogServices", "Journal", "Entries",
      bmcJournalLogEntryID);
  bmcJournalLogEntryJson["Name"] = "BMC Journal Entry";
  bmcJournalLogEntryJson["Id"] = bmcJournalLogEntryID;
  bmcJournalLogEntryJson["Message"] = std::move(message);
  bmcJournalLogEntryJson["EntryType"] = "Oem";
  bmcJournalLogEntryJson["Severity"] = severity <= 2   ? "Critical"
                                       : severity <= 4 ? "Warning"
                                                       : "OK";
  bmcJournalLogEntryJson["OemRecordFormat"] = "BMC Journal Entry";
  bmcJournalLogEntryJson["Created"] = std::move(entryTimeStr);
  return 0;
}

inline void handleGetBMCJournalLogEntryCollection(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  query_param::QueryCapabilities capabilities = {
      .canDelegateTop = true,
      .canDelegateSkip = true,
  };
  query_param::Query delegatedQuery;
  if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
                                                delegatedQuery, capabilities)) {
    return;
  }

  size_t skip = delegatedQuery.skip.value_or(0);
  size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);

  // Collections don't include the static data added by SubRoute
  // because it has a duplicate entry for members
  asyncResp->res.jsonValue["@odata.type"] =
      "#LogEntryCollection.LogEntryCollection";
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Managers/bmc/LogServices/Journal/Entries";
  asyncResp->res.jsonValue["Name"] = "Open BMC Journal Entries";
  asyncResp->res.jsonValue["Description"] = "Collection of BMC Journal Entries";
  nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
  logEntryArray = nlohmann::json::array();

  // Go through the journal and use the timestamp to create a
  // unique ID for each entry
  sd_journal* journalTmp = nullptr;
  int ret = sd_journal_open(&journalTmp, SD_JOURNAL_LOCAL_ONLY);
  if (ret < 0) {
    BMCWEB_LOG_ERROR << "failed to open journal: " << strerror(-ret);
    messages::internalError(asyncResp->res);
    return;
  }
  std::unique_ptr<sd_journal, decltype(&sd_journal_close)> journal(
      journalTmp, sd_journal_close);
  journalTmp = nullptr;
  uint64_t entryCount = 0;
  // Reset the unique ID on the first entry
  bool firstEntry = true;
  SD_JOURNAL_FOREACH(journal.get()) {
    entryCount++;
    // Handle paging using skip (number of entries to skip from
    // the start) and top (number of entries to display)
    if (entryCount <= skip || entryCount > skip + top) {
      continue;
    }

    std::string idStr;
    if (!getUniqueEntryID(journal.get(), idStr, firstEntry)) {
      continue;
    }
    firstEntry = false;

    nlohmann::json::object_t bmcJournalLogEntry;
    if (fillBMCJournalLogEntryJson(idStr, journal.get(), bmcJournalLogEntry) !=
        0) {
      messages::internalError(asyncResp->res);
      return;
    }
    logEntryArray.push_back(std::move(bmcJournalLogEntry));
  }
  asyncResp->res.jsonValue["Members@odata.count"] = entryCount;
  if (skip + top < entryCount) {
    asyncResp->res.jsonValue["Members@odata.nextLink"] =
        "/redfish/v1/Managers/bmc/LogServices/Journal/Entries?$skip=" +
        std::to_string(skip + top);
  }
}

void requestRoutesBMCJournalLogEntryCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Journal/Entries/")
      .privileges(redfish::privileges::getLogEntryCollection)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleGetBMCJournalLogEntryCollection, std::ref(app)));
}

inline void handleGetBMCJournalLogEntry(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& entryID) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  // Convert the unique ID back to a timestamp to find the entry
  uint64_t ts = 0;
  uint64_t index = 0;
  if (!getTimestampFromID(asyncResp, entryID, ts, index)) {
    return;
  }

  sd_journal* journalTmp = nullptr;
  int ret = sd_journal_open(&journalTmp, SD_JOURNAL_LOCAL_ONLY);
  if (ret < 0) {
    BMCWEB_LOG_ERROR << "failed to open journal: " << strerror(-ret);
    messages::internalError(asyncResp->res);
    return;
  }
  std::unique_ptr<sd_journal, decltype(&sd_journal_close)> journal(
      journalTmp, sd_journal_close);
  journalTmp = nullptr;
  // Go to the timestamp in the log and move to the entry at the
  // index tracking the unique ID
  std::string idStr;
  bool firstEntry = true;
  ret = sd_journal_seek_realtime_usec(journal.get(), ts);
  if (ret < 0) {
    BMCWEB_LOG_ERROR << "failed to seek to an entry in journal"
                     << strerror(-ret);
    messages::internalError(asyncResp->res);
    return;
  }
  for (uint64_t i = 0; i <= index; i++) {
    sd_journal_next(journal.get());
    if (!getUniqueEntryID(journal.get(), idStr, firstEntry)) {
      messages::internalError(asyncResp->res);
      return;
    }
    firstEntry = false;
  }
  // Confirm that the entry ID matches what was requested
  if (idStr != entryID) {
    messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
    return;
  }

  nlohmann::json::object_t bmcJournalLogEntry;
  if (fillBMCJournalLogEntryJson(entryID, journal.get(), bmcJournalLogEntry) !=
      0) {
    messages::internalError(asyncResp->res);
    return;
  }
  asyncResp->res.jsonValue.update(bmcJournalLogEntry);
}

void requestRoutesBMCJournalLogEntry(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/LogServices/Journal/Entries/<str>/")
      .privileges(redfish::privileges::getLogEntry)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetBMCJournalLogEntry, std::ref(app)));
}

namespace internal {
void getDumpServiceInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                        const Dump& dump) {
  std::string dumpPath;
  std::string overWritePolicy;
  bool collectDiagnosticDataSupported = false;

  switch (dump.type) {
    case DumpType::BMC_DUMP:
      dumpPath = "/redfish/v1/Managers/bmc/LogServices/Dump";
      overWritePolicy = "WrapsWhenFull";
      collectDiagnosticDataSupported = true;
      break;
    case DumpType::BMC_FAULT_LOG:
      dumpPath = "/redfish/v1/Managers/bmc/LogServices/FaultLog";
      overWritePolicy = "Unknown";
      collectDiagnosticDataSupported = false;
      break;
    case DumpType::SYSTEM_DUMP:
      dumpPath = "/redfish/v1/Systems/system/LogServices/Dump";
      overWritePolicy = "WrapsWhenFull";
      collectDiagnosticDataSupported = true;
      break;
    case DumpType::SYSTEM_FAULT_LOG:
      if (dump.systemName) {
        dumpPath =
            "/redfish/v1/Systems/" + *dump.systemName + "/LogServices/FaultLog";
        overWritePolicy = "Unknown";
        collectDiagnosticDataSupported = false;
      }
      break;
  }

  asyncResp->res.jsonValue["@odata.id"] = dumpPath;
  asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
  asyncResp->res.jsonValue["Name"] =
      dumpTypeToString(dump.type) + " Dump LogService";
  asyncResp->res.jsonValue["Description"] =
      dumpTypeToString(dump.type) + " Dump LogService";
  asyncResp->res.jsonValue["Id"] = std::filesystem::path(dumpPath).filename();
  asyncResp->res.jsonValue["OverWritePolicy"] = std::move(overWritePolicy);

  std::pair<std::string, std::string> redfishDateTimeOffset =
      redfish::time_utils::getDateTimeOffsetNow();
  asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
  asyncResp->res.jsonValue["DateTimeLocalOffset"] =
      redfishDateTimeOffset.second;

  asyncResp->res.jsonValue["Entries"]["@odata.id"] = dumpPath + "/Entries";

  if (collectDiagnosticDataSupported) {
    asyncResp->res
        .jsonValue["Actions"]["#LogService.CollectDiagnosticData"]["target"] =
        dumpPath + "/Actions/LogService.CollectDiagnosticData";
  }

  constexpr std::array<std::string_view, 1> interfaces = {deleteAllInterface};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/xyz/openbmc_project/dump", 0, interfaces, requestContext,
      [asyncResp, dump, dumpPath](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreePathsResponse& subTreePaths) {
        if (ec) {
          BMCWEB_LOG_ERROR << "getDumpServiceInfo respHandler got error " << ec;
          // Assume that getting an error simply means there are no dump
          // LogServices. Return without adding any error response.
          return;
        }

        std::optional<std::string> dumpManagerCollectionPath =
            getDumpManagerCollectionPath(dump);

        if (!dumpManagerCollectionPath) {
          BMCWEB_LOG_ERROR << "Cant get dumpManagerCollectionPath from system "
                           << dump.systemName.value_or("none");
          messages::internalError(asyncResp->res);
          return;
        }

        for (const std::string& path : subTreePaths) {
          if (path == *dumpManagerCollectionPath) {
            asyncResp->res
                .jsonValue["Actions"]["#LogService.ClearLog"]["target"] =
                dumpPath + "/Actions/LogService.ClearLog";
            break;
          }
        }
      });
}
}  // namespace internal

inline void handleLogServicesDumpServiceGet(
    crow::App& app, DumpType dumpType, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  internal::getDumpServiceInfo(asyncResp, Dump{.type = dumpType});
}

inline void handleLogServicesDumpServiceComputerSystemGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& id) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  if (id != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", id);
    return;
  }
  internal::getDumpServiceInfo(asyncResp, Dump{.type = DumpType::SYSTEM_DUMP});
}

inline void handleLogServicesDumpEntriesCollectionGet(
    crow::App& app, DumpType dumpType, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  query_param::QueryCapabilities capabilities = {
      .canDelegateExpandLevel = 2,
      .canDelegateFilter = true,
  };
  query_param::Query delegatedQuery;
  if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
                                                delegatedQuery, capabilities)) {
    return;
  }
  getDumpEntryCollection(app, req, asyncResp, Dump{.type = dumpType},
                         delegatedQuery);
}

inline void handleLogServicesDumpEntriesCollectionComputerSystemGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId) {
  query_param::QueryCapabilities capabilities = {
      .canDelegateExpandLevel = 2,
      .canDelegateFilter = true,
  };
  query_param::Query delegatedQuery;

  if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
                                                delegatedQuery, capabilities)) {
    return;
  }
  if (chassisId != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
    return;
  }
  getDumpEntryCollection(app, req, asyncResp,
                         Dump{.type = DumpType::SYSTEM_DUMP}, delegatedQuery);
}

inline void handleLogServicesDumpEntryGet(
    crow::App& app, DumpType dumpType, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& dumpId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  getDumpEntryById(asyncResp, dumpId, Dump{.type = dumpType});
}

inline void handleLogServicesDumpEntryComputerSystemGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& dumpId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  if (chassisId != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
    return;
  }
  getDumpEntryById(asyncResp, dumpId, Dump{.type = DumpType::SYSTEM_DUMP});
}

inline void handleLogServicesDumpEntryDelete(
    crow::App& app, DumpType dumpType, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& dumpId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  deleteDumpEntry(asyncResp, dumpId, Dump{.type = dumpType});
}

inline void handleLogServicesDumpEntryComputerSystemDelete(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& dumpId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  if (chassisId != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
    return;
  }
  deleteDumpEntry(asyncResp, dumpId, Dump{.type = DumpType::SYSTEM_DUMP});
}

inline void handleLogServicesDumpEntryDownloadGet(
    crow::App& app, DumpType dumpType, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& dumpId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  downloadDumpEntry(asyncResp, dumpId, Dump{.type = dumpType});
}

inline void handleLogServicesDumpCollectDiagnosticDataPost(
    crow::App& app, DumpType dumpType, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  createDump(asyncResp, req, Dump{.type = dumpType});
}

inline void handleLogServicesDumpCollectDiagnosticDataComputerSystemPost(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  if (chassisId != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
    return;
  }
  createDump(asyncResp, req, Dump{.type = DumpType::SYSTEM_DUMP});
}

inline void handleLogServicesDumpClearLogPost(
    crow::App& app, DumpType dumpType, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  clearDump(asyncResp, Dump{.type = dumpType});
}

inline void handleLogServicesDumpClearLogComputerSystemPost(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  if (chassisId != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
    return;
  }
  clearDump(asyncResp, Dump{.type = DumpType::SYSTEM_DUMP});
}

inline void handleLogServiceFaultLogEntriesGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  query_param::QueryCapabilities capabilities = {
      .canDelegateExpandLevel = 2,
      .canDelegateFilter = true,
  };
  query_param::Query delegatedQuery;
  if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
                                                delegatedQuery, capabilities)) {
    return;
  }
  getDumpEntryCollection(
      app, req, asyncResp,
      Dump{.type = DumpType::SYSTEM_FAULT_LOG, .systemName = systemName},
      delegatedQuery);
}

void requestRoutesBMCDumpService(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Dump/")
      .privileges(redfish::privileges::getLogService)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleLogServicesDumpServiceGet, std::ref(app), DumpType::BMC_DUMP));
}

void requestRoutesBMCDumpEntryCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/")
      .privileges(redfish::privileges::getLogEntryCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleLogServicesDumpEntriesCollectionGet,
                          std::ref(app), DumpType::BMC_DUMP));
}

void requestRoutesBMCDumpEntry(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/<str>/")
      .privileges(redfish::privileges::getLogEntry)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleLogServicesDumpEntryGet, std::ref(app), DumpType::BMC_DUMP));

  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/<str>/")
      .privileges(redfish::privileges::deleteLogEntry)
      .methods(boost::beast::http::verb::delete_)(std::bind_front(
          handleLogServicesDumpEntryDelete, std::ref(app), DumpType::BMC_DUMP));
}

void requestRoutesBMCDumpEntryDownload(App& app) {
  BMCWEB_ROUTE(
      app, "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/<str>/attachment")
      .privileges(redfish::privileges::getLogEntry)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleLogServicesDumpEntryDownloadGet, std::ref(app),
                          DumpType::BMC_DUMP));
}

void requestRoutesBMCDumpCreate(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/LogServices/Dump/Actions/"
               "LogService.CollectDiagnosticData/")
      .privileges(redfish::privileges::postLogService)
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handleLogServicesDumpCollectDiagnosticDataPost,
                          std::ref(app), DumpType::BMC_DUMP));
}

void requestRoutesBMCDumpClear(App& app) {
  BMCWEB_ROUTE(
      app,
      "/redfish/v1/Managers/bmc/LogServices/Dump/Actions/LogService.ClearLog/")
      .privileges(redfish::privileges::postLogService)
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handleLogServicesDumpClearLogPost, std::ref(app),
                          DumpType::BMC_DUMP));
}

void requestRoutesFaultLogDumpService(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/FaultLog/")
      .privileges(redfish::privileges::getLogService)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleLogServicesDumpServiceGet, std::ref(app),
                          DumpType::BMC_FAULT_LOG));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/FaultLog/")
      .privileges(redfish::privileges::getLogService)
      .methods(boost::beast::http::verb::get)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& systemName) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }
            internal::getDumpServiceInfo(
                asyncResp, Dump{.type = DumpType::SYSTEM_FAULT_LOG,
                                .systemName = systemName});
          });
}

void requestRoutesFaultLogDumpEntryCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/FaultLog/Entries/")
      .privileges(redfish::privileges::getLogEntryCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleLogServicesDumpEntriesCollectionGet,
                          std::ref(app), DumpType::BMC_FAULT_LOG));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/FaultLog/Entries/")
      .privileges(redfish::privileges::getLogEntryCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleLogServiceFaultLogEntriesGet, std::ref(app)));
}

void requestRoutesFaultLogDumpEntry(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/LogServices/FaultLog/Entries/<str>/")
      .privileges(redfish::privileges::getLogEntry)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleLogServicesDumpEntryGet, std::ref(app),
                          DumpType::BMC_FAULT_LOG));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/FaultLog/Entries/<str>/")
      .privileges(redfish::privileges::getLogEntry)
      .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& dumpId) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }
            getDumpEntryById(asyncResp, dumpId,
                             Dump{.type = DumpType::SYSTEM_FAULT_LOG,
                                  .systemName = systemName});
          });

  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/LogServices/FaultLog/Entries/<str>/")
      .privileges(redfish::privileges::deleteLogEntry)
      .methods(boost::beast::http::verb::delete_)(
          std::bind_front(handleLogServicesDumpEntryDelete, std::ref(app),
                          DumpType::BMC_FAULT_LOG));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/FaultLog/Entries/<str>/")
      .privileges(redfish::privileges::deleteLogEntry)
      .methods(boost::beast::http::verb::delete_)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& systemName, const std::string& dumpId) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }
            deleteDumpEntry(asyncResp, dumpId,
                            Dump{.type = DumpType::SYSTEM_FAULT_LOG,
                                 .systemName = systemName});
          });
}

void requestRoutesFaultLogDumpClear(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/LogServices/FaultLog/Actions/"
               "LogService.ClearLog/")
      .privileges(redfish::privileges::postLogService)
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handleLogServicesDumpClearLogPost, std::ref(app),
                          DumpType::BMC_FAULT_LOG));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/FaultLog/Actions/"
               "LogService.ClearLog/")
      .privileges(redfish::privileges::postLogService)
      .methods(boost::beast::http::verb::post)(
          [&app](const crow::Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& systemName) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }
            clearDump(asyncResp, Dump{.type = DumpType::SYSTEM_FAULT_LOG,
                                      .systemName = systemName});
          });
}

void requestRoutesSystemDumpService(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/")
      .privileges(redfish::privileges::getLogService)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleLogServicesDumpServiceComputerSystemGet, std::ref(app)));
}

void requestRoutesSystemDumpEntryCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/")
      .privileges(redfish::privileges::getLogEntryCollection)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleLogServicesDumpEntriesCollectionComputerSystemGet,
          std::ref(app)));
}

void requestRoutesSystemDumpEntry(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
      .privileges(redfish::privileges::getLogEntry)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleLogServicesDumpEntryComputerSystemGet, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
      .privileges(redfish::privileges::deleteLogEntry)
      .methods(boost::beast::http::verb::delete_)(std::bind_front(
          handleLogServicesDumpEntryComputerSystemDelete, std::ref(app)));
}

void requestRoutesSystemDumpCreate(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/"
               "LogService.CollectDiagnosticData/")
      .privileges(redfish::privileges::postLogService)
      .methods(boost::beast::http::verb::post)(std::bind_front(
          handleLogServicesDumpCollectDiagnosticDataComputerSystemPost,
          std::ref(app)));
}

void requestRoutesSystemDumpClear(App& app) {
  BMCWEB_ROUTE(
      app,
      "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
      .privileges(redfish::privileges::postLogService)
      .methods(boost::beast::http::verb::post)(std::bind_front(
          handleLogServicesDumpClearLogComputerSystemPost, std::ref(app)));
}

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

  // Copy over the static data to include the entries added by
  // SubRoute
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/system/LogServices/HostCper";
  asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
  asyncResp->res.jsonValue["Name"] = "Open BMC Oem RasManager Service";
  asyncResp->res.jsonValue["Description"] = "Oem RasManager Service";
  asyncResp->res.jsonValue["Id"] = "RasManager";
  asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";

  std::pair<std::string, std::string> redfishDateTimeOffset =
      redfish::time_utils::getDateTimeOffsetNow();
  asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
  asyncResp->res.jsonValue["DateTimeLocalOffset"] =
      redfishDateTimeOffset.second;

  asyncResp->res.jsonValue["Entries"]["@odata.id"] =
      crow::utility::urlFromPieces("redfish", "v1", "Systems", "system",
                                   "LogServices", "HostCper", "Entries");
  asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]["target"] =
      "/redfish/v1/Systems/system/LogServices/HostCper/Actions/"
      "LogService.ClearLog";
}

void requestRoutesRasManagerLogService(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/HostCper/")
      .privileges({{"ConfigureManager"}})
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleLogServicesRasManagerGet, std::ref(app)));
}

inline void handleLogServicesRasManagerClearLogPost(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  if (systemName != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", systemName);
    return;
  }
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp](const boost::system::error_code& ec, const std::string&) {
        if (ec) {
          messages::internalError(asyncResp->res);
          return;
        }
        messages::success(asyncResp->res);
      },
      rasManagerObject, rasManagerPath, deleteAllInterface, "DeleteAll");
}

void requestRoutesRasManagerLogClear(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/HostCper/Actions/"
               "LogService.ClearLog/")
      .privileges({{"ConfigureComponents"}})
      .methods(boost::beast::http::verb::post)(std::bind_front(
          handleLogServicesRasManagerClearLogPost, std::ref(app)));
}

inline static void logRasManagerEntry(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& logID, nlohmann::json& logEntryJson) {
  auto getStoredLogCallback =
      [asyncResp, logID, &logEntryJson](
          const boost::system::error_code& ec,
          const dbus::utility::DBusPropertiesMap& params) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "failed to get log ec: " << ec.message();
          if (ec.value() ==
              boost::system::linux_error::bad_request_descriptor) {
            messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
          } else {
            messages::internalError(asyncResp->res);
          }
          return;
        }

        uint64_t timestampMs = 0;
        const uint64_t* timestampPtr = nullptr;
        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), params, "TimestampMs",
            timestampPtr);

        if (!success) {
          return;
        }

        if (timestampPtr != nullptr) {
          timestampMs = *timestampPtr;
        }

        nlohmann::json::object_t logEntry;
        logEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
        logEntry["@odata.id"] = crow::utility::urlFromPieces(
            "redfish", "v1", "Systems", "system", "LogServices", "HostCper",
            "Entries", logID);
        logEntry["Name"] = "RasManager";
        logEntry["Id"] = logID;
        logEntry["EntryType"] = "Oem";
        logEntry["DiagnosticDataType"] = "CPER";
        logEntry["OemRecordFormat"] = "CPER";
        logEntry["Created"] =
            redfish::time_utils::getDateTimeUintMs(timestampMs);

        // read bin data from file and then encode it to boost base64
        std::string cperFile = rasManagerLogPath + logID + ".cpr";
        std::ifstream ifs(cperFile, std::ios::in | std::ios::binary);
        if (!ifs.is_open()) {
          BMCWEB_LOG_ERROR << "Failed to open file: " << cperFile;
          return;
        }
        std::string cperData((std::istreambuf_iterator<char>(ifs)),
                             (std::istreambuf_iterator<char>()));
        std::string encodedData;
        encodedData.resize(
            boost::beast::detail::base64::encoded_size(cperData.size()));
        encodedData.resize(boost::beast::detail::base64::encode(
            &encodedData[0], cperData.data(), cperData.size()));
        logEntry["DiagnosticData"] = std::move(encodedData);
        ifs.close();

        // If logEntryJson references an array of LogEntry resources
        // ('Members' list), then push this as a new entry, otherwise set it
        // directly
        if (logEntryJson.is_array()) {
          logEntryJson.push_back(logEntry);
          asyncResp->res.jsonValue["Members@odata.count"] = logEntryJson.size();
        } else {
          logEntryJson.update(logEntry);
        }
      };
  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      rasManagerObject, rasManagerPath + std::string("/") + logID,
      "xyz.openbmc_project.Time.EpochTime", context,
      std::move(getStoredLogCallback));
}

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

  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Time.EpochTime"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      rasManagerPath, 0, interfaces, requestContext,
      [asyncResp](const boost::system::error_code& ec,
                  const std::vector<std::string>& resp) {
        if (ec) {
          if (ec.value() != boost::system::errc::no_such_file_or_directory) {
            BMCWEB_LOG_DEBUG << "failed to get entries ec: " << ec.message();
            messages::internalError(asyncResp->res);
            return;
          }
        }
        asyncResp->res.jsonValue["@odata.type"] =
            "#LogEntryCollection.LogEntryCollection";
        asyncResp->res.jsonValue["@odata.id"] =
            "/redfish/v1/Systems/system/LogServices/HostCper/Entries";
        asyncResp->res.jsonValue["Name"] = "Open BMC RasManager Entries";
        asyncResp->res.jsonValue["Description"] =
            "Collection of RasManager Entries";
        asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
        asyncResp->res.jsonValue["Members@odata.count"] = 0;

        for (const std::string& path : resp) {
          const sdbusplus::message::object_path objPath(path);
          // Get the log ID
          std::string logID = objPath.filename();
          if (logID.empty()) {
            continue;
          }
          // Add the log entry to the array
          logRasManagerEntry(asyncResp, logID,
                             asyncResp->res.jsonValue["Members"]);
        }
      });
}

void requestRoutesRasManagerLogEntryCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/HostCper/Entries/")
      .privileges({{"ConfigureComponents"}})
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleLogServicesRasManagerEntriesCollectionGet, std::ref(app)));
}

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

  logRasManagerEntry(asyncResp, logID, asyncResp->res.jsonValue);
}

void requestRoutesRasManagerLogEntry(App& app) {
  // Note: Deviated from redfish privilege registry for GET & HEAD
  // method for security reasons.

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/HostCper/Entries/<str>/")
      .privileges({{"ConfigureComponents"}})
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleLogServicesRasManagerEntryGet, std::ref(app)));
}
#endif  // BMCWEB_ENABLE_RASMANAGER_EVENT_LOG

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

  // Copy over the static data to include the entries added by
  // SubRoute
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/system/LogServices/Crashdump";
  asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
  asyncResp->res.jsonValue["Name"] = "Open BMC Oem Crashdump Service";
  asyncResp->res.jsonValue["Description"] = "Oem Crashdump Service";
  asyncResp->res.jsonValue["Id"] = "Crashdump";
  asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
  if constexpr (bmcwebEnableAmd) {
    asyncResp->res.jsonValue["MaxNumberOfRecords"] = 10;
  } else {
    asyncResp->res.jsonValue["MaxNumberOfRecords"] = 3;
  }

  std::pair<std::string, std::string> redfishDateTimeOffset =
      redfish::time_utils::getDateTimeOffsetNow();
  asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
  asyncResp->res.jsonValue["DateTimeLocalOffset"] =
      redfishDateTimeOffset.second;

  asyncResp->res.jsonValue["Entries"]["@odata.id"] =
      crow::utility::urlFromPieces("redfish", "v1", "Systems", "system",
                                   "LogServices", "Crashdump", "Entries");
  asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]["target"] =
      "/redfish/v1/Systems/system/LogServices/Crashdump/Actions/"
      "LogService.ClearLog";
  asyncResp->res
      .jsonValue["Actions"]["#LogService.CollectDiagnosticData"]["target"] =
      "/redfish/v1/Systems/system/LogServices/Crashdump/Actions/"
      "LogService.CollectDiagnosticData";
}

void requestRoutesCrashdumpService(App& app) {
  // Note: Deviated from redfish privilege registry for GET & HEAD
  // method for security reasons.
  /**
   * Functions triggers appropriate requests on DBus
   */
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/")
      // This is incorrect, should be:
      // .privileges(redfish::privileges::getLogService)
      .privileges({{"ConfigureManager"}})
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetCrashdumpService, std::ref(app)));
}

inline void handlePostCrashdumpClear(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  if (systemName != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", systemName);
    return;
  }
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp](const boost::system::error_code& ec, const std::string&) {
        if (ec) {
          messages::internalError(asyncResp->res);
          return;
        }
        messages::success(asyncResp->res);
      },
      crashdumpObject, crashdumpPath, deleteAllInterface, "DeleteAll");
}

void requestRoutesCrashdumpClear(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/"
               "LogService.ClearLog/")
      // This is incorrect, should be:
      // .privileges(redfish::privileges::postLogService)
      .privileges({{"ConfigureComponents"}})
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handlePostCrashdumpClear, std::ref(app)));
}

inline static void logCrashdumpEntry(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& logID, nlohmann::json& logEntryJson) {
  auto getStoredLogCallback =
      [asyncResp, logID, &logEntryJson](
          const boost::system::error_code& ec,
          const dbus::utility::DBusPropertiesMap& params) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "failed to get log ec: " << ec.message();
          if (ec.value() ==
              boost::system::linux_error::bad_request_descriptor) {
            messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
          } else {
            messages::internalError(asyncResp->res);
          }
          return;
        }

        std::string timestamp{};
        std::string filename{};
        std::string logfile{};
        parseCrashdumpParameters(params, filename, timestamp, logfile);

        if (filename.empty() || timestamp.empty()) {
          messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
          return;
        }

        std::string crashdumpURI =
            "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/" +
            logID + "/" + filename;
        nlohmann::json::object_t logEntry;
        logEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
        logEntry["@odata.id"] = crow::utility::urlFromPieces(
            "redfish", "v1", "Systems", "system", "LogServices", "Crashdump",
            "Entries", logID);
        logEntry["Name"] = "CPU Crashdump";
        logEntry["Id"] = logID;
        logEntry["EntryType"] = "Oem";
        logEntry["AdditionalDataURI"] = std::move(crashdumpURI);
        logEntry["DiagnosticDataType"] = "OEM";
        if constexpr (bmcwebEnableAmd) {
          logEntry["OEMDiagnosticDataType"] = "CPER";
        } else {
          logEntry["OEMDiagnosticDataType"] = "PECICrashdump";
        }
        logEntry["Created"] = std::move(timestamp);

        // If logEntryJson references an array of LogEntry resources
        // ('Members' list), then push this as a new entry, otherwise set it
        // directly
        if (logEntryJson.is_array()) {
          logEntryJson.push_back(logEntry);
          asyncResp->res.jsonValue["Members@odata.count"] = logEntryJson.size();
        } else {
          logEntryJson.update(logEntry);
        }
      };
  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      crashdumpObject, crashdumpPath + std::string("/") + logID,
      crashdumpInterface, context, std::move(getStoredLogCallback));
}

inline void parseElapsedTimestampFromDbusObject(
    const dbus::utility::ManagedObjectType::value_type& object,
    uint64_t& timestampUs,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  for (const auto& interfaceMap : object.second) {
    if (interfaceMap.first == "xyz.openbmc_project.Time.EpochTime") {
      for (const auto& propertyMap : interfaceMap.second) {
        if (propertyMap.first == "Elapsed") {
          const uint64_t* usecsTimeStamp =
              std::get_if<uint64_t>(&propertyMap.second);
          if (usecsTimeStamp == nullptr) {
            messages::internalError(asyncResp->res);
            break;
          }
          timestampUs = *usecsTimeStamp;
          break;
        }
      }
      break;
    }
  }
}

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

  constexpr std::array<std::string_view, 1> interfaces = {crashdumpInterface};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/", 0, interfaces, requestContext,
      [asyncResp](const boost::system::error_code& ec,
                  const std::vector<std::string>& resp) {
        if (ec) {
          if (ec.value() != boost::system::errc::no_such_file_or_directory) {
            BMCWEB_LOG_DEBUG << "failed to get entries ec: " << ec.message();
            messages::internalError(asyncResp->res);
            return;
          }
        }
        asyncResp->res.jsonValue["@odata.type"] =
            "#LogEntryCollection.LogEntryCollection";
        asyncResp->res.jsonValue["@odata.id"] =
            "/redfish/v1/Systems/system/LogServices/Crashdump/Entries";
        asyncResp->res.jsonValue["Name"] = "Open BMC Crashdump Entries";
        asyncResp->res.jsonValue["Description"] =
            "Collection of Crashdump Entries";
        asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
        asyncResp->res.jsonValue["Members@odata.count"] = 0;

        for (const std::string& path : resp) {
          const sdbusplus::message::object_path objPath(path);
          // Get the log ID
          std::string logID = objPath.filename();
          if (logID.empty()) {
            continue;
          }
          // Add the log entry to the array
          logCrashdumpEntry(asyncResp, logID,
                            asyncResp->res.jsonValue["Members"]);
        }
      });
}

void requestRoutesCrashdumpEntryCollection(App& app) {
  // Note: Deviated from redfish privilege registry for GET & HEAD
  // method for security reasons.
  /**
   * Functions triggers appropriate requests on DBus
   */
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/")
      // This is incorrect, should be.
      // .privileges(redfish::privileges::postLogEntryCollection)
      .privileges({{"ConfigureComponents"}})
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetCrashdumpEntryCollection, std::ref(app)));
}

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

  logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue);
}

void requestRoutesCrashdumpEntry(App& app) {
  // Note: Deviated from redfish privilege registry for GET & HEAD
  // method for security reasons.

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/")
      // this is incorrect, should be
      // .privileges(redfish::privileges::getLogEntry)
      .privileges({{"ConfigureComponents"}})
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetCrashdumpEntry, std::ref(app)));
}

inline void handleGetCrashdumpFile(
    [[maybe_unused]] App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& logID,
    const std::string& fileName) {
  // Do not call getRedfishRoute here since the crashdump file is not a
  // Redfish resource.

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

  auto getStoredLogCallback =
      [asyncResp, logID, fileName, url(boost::urls::url(req.url()))](
          const boost::system::error_code& ec,
          const std::vector<
              std::pair<std::string, dbus::utility::DbusVariantType>>& resp) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "failed to get log ec: " << ec.message();
          messages::internalError(asyncResp->res);
          return;
        }

        std::string dbusFilename{};
        std::string dbusTimestamp{};
        std::string dbusFilepath{};

        parseCrashdumpParameters(resp, dbusFilename, dbusTimestamp,
                                 dbusFilepath);

        if (dbusFilename.empty() || dbusTimestamp.empty() ||
            dbusFilepath.empty()) {
          messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
          return;
        }

        // Verify the file name parameter is correct
        if (fileName != dbusFilename) {
          messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
          return;
        }

        if (!std::filesystem::exists(dbusFilepath)) {
          messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
          return;
        }
        std::ifstream ifs(dbusFilepath, std::ios::in | std::ios::binary);
        asyncResp->res.body() =
            std::string(std::istreambuf_iterator<char>{ifs}, {});

        // Configure this to be a file download when accessed
        // from a browser
        asyncResp->res.addHeader(boost::beast::http::field::content_disposition,
                                 "attachment");
      };
  managedStore::ManagedObjectStoreContext context(asyncResp);
  managedStore::GetManagedObjectStore()->getAllProperties(
      crashdumpObject, crashdumpPath + std::string("/") + logID,
      crashdumpInterface, context, std::move(getStoredLogCallback));
}

void requestRoutesCrashdumpFile(App& app) {
  // Note: Deviated from redfish privilege registry for GET & HEAD
  // method for security reasons.
  BMCWEB_ROUTE(
      app,
      "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/<str>/")
      .privileges(redfish::privileges::getLogEntry)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetCrashdumpFile, std::ref(app)));
}

enum class OEMDiagnosticType : std::uint8_t {
  onDemand,
  telemetry,
  invalid,
};

inline OEMDiagnosticType getOEMDiagnosticType(std::string_view oemDiagStr) {
  if (oemDiagStr == "OnDemand") {
    return OEMDiagnosticType::onDemand;
  }
  if (oemDiagStr == "Telemetry") {
    return OEMDiagnosticType::telemetry;
  }

  return OEMDiagnosticType::invalid;
}

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

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

  std::string diagnosticDataType;
  std::string oemDiagnosticDataType;
  if (!redfish::json_util::readJsonAction(
          req, asyncResp->res, "DiagnosticDataType", diagnosticDataType,
          "OEMDiagnosticDataType", oemDiagnosticDataType)) {
    return;
  }

  if (diagnosticDataType != "OEM") {
    BMCWEB_LOG_ERROR << "Only OEM DiagnosticDataType supported for Crashdump";
    messages::actionParameterValueFormatError(
        asyncResp->res, diagnosticDataType, "DiagnosticDataType",
        "CollectDiagnosticData");
    return;
  }

  OEMDiagnosticType oemDiagType = getOEMDiagnosticType(oemDiagnosticDataType);

  std::string iface;
  std::string method;
  std::string taskMatchStr;
  if (oemDiagType == OEMDiagnosticType::onDemand) {
    iface = crashdumpOnDemandInterface;
    method = "GenerateOnDemandLog";
    if constexpr (bmcwebEnableAmd) {
      taskMatchStr =
          "type='signal',"
          "interface='org.freedesktop.DBus.Properties',"
          "member='PropertiesChanged',"
          "arg0namespace='com.amd.crashdump'";
    } else {
      taskMatchStr =
          "type='signal',"
          "interface='org.freedesktop.DBus.Properties',"
          "member='PropertiesChanged',"
          "arg0namespace='com.intel.crashdump'";
    }
  } else if (oemDiagType == OEMDiagnosticType::telemetry) {
    iface = crashdumpTelemetryInterface;
    method = "GenerateTelemetryLog";
    if constexpr (bmcwebEnableAmd) {
      taskMatchStr =
          "type='signal',"
          "interface='org.freedesktop.DBus.Properties',"
          "member='PropertiesChanged',"
          "arg0namespace='com.amd.crashdump'";
    } else {
      taskMatchStr =
          "type='signal',"
          "interface='org.freedesktop.DBus.Properties',"
          "member='PropertiesChanged',"
          "arg0namespace='com.intel.crashdump'";
    }
  } else {
    BMCWEB_LOG_ERROR << "Unsupported OEMDiagnosticDataType: "
                     << oemDiagnosticDataType;
    messages::actionParameterValueFormatError(
        asyncResp->res, oemDiagnosticDataType, "OEMDiagnosticDataType",
        "CollectDiagnosticData");
    return;
  }

  auto collectCrashdumpCallback = [asyncResp, payload(task::Payload(req)),
                                   taskMatchStr](
                                      const boost::system::error_code& ec,
                                      const std::string&) mutable {
    if (ec) {
      if (ec.value() == boost::system::errc::operation_not_supported) {
        messages::resourceInStandby(asyncResp->res);
      } else if (ec.value() == boost::system::errc::device_or_resource_busy) {
        messages::serviceTemporarilyUnavailable(asyncResp->res, "60");
      } else {
        messages::internalError(asyncResp->res);
      }
      return;
    }
    std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
        [](const boost::system::error_code& err, sdbusplus::message_t&,
           const std::shared_ptr<task::TaskData>& taskData) {
          if (!err) {
            taskData->messages.emplace_back(
                messages::taskCompletedOK(std::to_string(taskData->index)));
            taskData->state = "Completed";
          }
          return task::completed;
        },
        taskMatchStr);

    task->startTimer(std::chrono::minutes(5));
    task->populateResp(asyncResp->res);
    task->payload.emplace(std::move(payload));
  };

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_, std::move(collectCrashdumpCallback), crashdumpObject,
      crashdumpPath, iface, method);
}

void requestRoutesCrashdumpCollect(App& app) {
  // Note: Deviated from redfish privilege registry for GET & HEAD
  // method for security reasons.
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/"
               "LogService.CollectDiagnosticData/")
      // The below is incorrect;  Should be ConfigureManager
      // .privileges(redfish::privileges::postLogService)
      .privileges({{"ConfigureComponents"}})
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handlePostCrashdumpCollect, std::ref(app)));
}

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

  // Process response from Logging service.
  auto respHandler = [asyncResp](const boost::system::error_code& ec) {
    BMCWEB_LOG_DEBUG << "doClearLog resp_handler callback: Done";
    if (ec) {
      // TODO Handle for specific error code
      BMCWEB_LOG_ERROR << "doClearLog resp_handler got error " << ec;
      asyncResp->res.result(boost::beast::http::status::internal_server_error);
      return;
    }

    asyncResp->res.result(boost::beast::http::status::no_content);
  };

  // Make call to Logging service to request Clear Log
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_, respHandler, "xyz.openbmc_project.Logging",
      "/xyz/openbmc_project/logging",
      "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
}

/**
 * DBusLogServiceActionsClear class supports POST method for ClearLog action.
 */
void requestRoutesDBusLogServiceActionsClear(App& app) {
  /**
   * Function handles POST method request.
   * The Clear Log actions does not require any parameter.The action deletes
   * all entries found in the Entries collection for this Log Service.
   */

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/"
               "LogService.ClearLog/")
      .privileges(redfish::privileges::postLogService)
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handlePostDBusLogServiceActionsClear, std::ref(app)));
}

inline void handleGetPostCodesLogService(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  if (systemName != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", systemName);
    return;
  }
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/system/LogServices/PostCodes";
  asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_1_0.LogService";
  asyncResp->res.jsonValue["Name"] = "POST Code Log Service";
  asyncResp->res.jsonValue["Description"] = "POST Code Log Service";
  asyncResp->res.jsonValue["Id"] = "PostCodes";
  asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
  asyncResp->res.jsonValue["Entries"]["@odata.id"] =
      "/redfish/v1/Systems/system/LogServices/PostCodes/Entries";

  std::pair<std::string, std::string> redfishDateTimeOffset =
      redfish::time_utils::getDateTimeOffsetNow();
  asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
  asyncResp->res.jsonValue["DateTimeLocalOffset"] =
      redfishDateTimeOffset.second;

  asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"] = {
      {"target",
       "/redfish/v1/Systems/system/LogServices/PostCodes/Actions/"
       "LogService.ClearLog"}};
}

/****************************************************
 * Redfish PostCode interfaces
 * using DBUS interface: getPostCodesTS
 ******************************************************/
void requestRoutesPostCodesLogService(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/PostCodes/")
      .privileges(redfish::privileges::getLogService)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetPostCodesLogService, std::ref(app)));
}

inline void handlePostPostCodesClear(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  if (systemName != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", systemName);
    return;
  }
  BMCWEB_LOG_DEBUG << "Do delete all postcodes entries.";

  // Make call to post-code service to request clear all
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp](const boost::system::error_code& ec) {
        if (ec) {
          // TODO Handle for specific error code
          BMCWEB_LOG_ERROR << "doClearPostCodes resp_handler got error " << ec;
          asyncResp->res.result(
              boost::beast::http::status::internal_server_error);
          messages::internalError(asyncResp->res);
          return;
        }
        messages::success(asyncResp->res);
      },
      "xyz.openbmc_project.State.Boot.PostCode0",
      "/xyz/openbmc_project/State/Boot/PostCode0",
      "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
}

void requestRoutesPostCodesClear(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/PostCodes/Actions/"
               "LogService.ClearLog/")
      // The following privilege is incorrect;  It should be ConfigureManager
      // .privileges(redfish::privileges::postLogService)
      .privileges({{"ConfigureComponents"}})
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handlePostPostCodesClear, std::ref(app)));
}

/**
 * @brief Parse post code ID and get the current value and index value
 *        eg: postCodeID=B1-2, currentValue=1, index=2
 *
 * @param[in]  postCodeID     Post Code ID
 * @param[out] currentValue   Current value
 * @param[out] index          Index value
 *
 * @return bool true if the parsing is successful, false the parsing fails
 */
inline static bool parsePostCode(const std::string& postCodeID,
                                 uint64_t& currentValue, uint16_t& index) {
  std::vector<std::string> split;
  bmcweb::split(split, postCodeID, '-');
  if (split.size() != 2 || split[0].length() < 2 || split[0].front() != 'B') {
    return false;
  }

  // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  const char* start = split[0].data() + 1;
  // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  const char* end = split[0].data() + split[0].size();
  auto [ptrIndex, ecIndex] = std::from_chars(start, end, index);

  if (ptrIndex != end || ecIndex != std::errc()) {
    return false;
  }

  start = split[1].data();

  // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  end = split[1].data() + split[1].size();
  auto [ptrValue, ecValue] = std::from_chars(start, end, currentValue);

  return ptrValue == end && ecValue == std::errc();
}

static bool fillPostCodeEntry(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const boost::container::flat_map<
        uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>& postcode,
    const uint16_t bootIndex, const uint64_t codeIndex = 0,
    const uint64_t skip = 0, const uint64_t top = 0) {
  // Get the Message from the MessageRegistry
  const registries::Message* message =
      registries::getMessage("OpenBMC.0.2.BIOSPOSTCode");

  uint64_t currentCodeIndex = 0;
  uint64_t firstCodeTimeUs = 0;
  for (const std::pair<uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>&
           code : postcode) {
    currentCodeIndex++;
    std::string postcodeEntryID =
        "B" + std::to_string(bootIndex) + "-" +
        std::to_string(currentCodeIndex);  // 1 based index in EntryID string

    uint64_t usecSinceEpoch = code.first;
    uint64_t usTimeOffset = 0;

    if (1 == currentCodeIndex) {  // already incremented
      firstCodeTimeUs = code.first;
    } else {
      usTimeOffset = code.first - firstCodeTimeUs;
    }

    // skip if no specific codeIndex is specified and currentCodeIndex does
    // not fall between top and skip
    if ((codeIndex == 0) &&
        (currentCodeIndex <= skip || currentCodeIndex > top)) {
      continue;
    }

    // skip if a specific codeIndex is specified and does not match the
    // currentIndex
    if ((codeIndex > 0) && (currentCodeIndex != codeIndex)) {
      // This is done for simplicity. 1st entry is needed to calculate
      // time offset. To improve efficiency, one can get to the entry
      // directly (possibly with flatmap's nth method)
      continue;
    }

    // currentCodeIndex is within top and skip or equal to specified code
    // index

    // Get the Created time from the timestamp
    std::string entryTimeStr;
    entryTimeStr = redfish::time_utils::getDateTimeUintUs(usecSinceEpoch);

    // assemble messageArgs: BootIndex, TimeOffset(100us), PostCode(hex)
    std::ostringstream hexCode;
    hexCode << "0x" << std::setfill('0') << std::setw(2) << std::hex
            << std::get<0>(code.second);
    std::ostringstream timeOffsetStr;
    // Set Fixed -Point Notation
    timeOffsetStr << std::fixed;
    // Set precision to 4 digits
    timeOffsetStr << std::setprecision(4);
    // Add double to stream
    timeOffsetStr << static_cast<double>(usTimeOffset) / 1000 / 1000;
    std::vector<std::string> messageArgs = {std::to_string(bootIndex),
                                            timeOffsetStr.str(), hexCode.str()};

    // Get MessageArgs template from message registry
    std::string msg;
    if (message != nullptr) {
      msg = message->message;

      // fill in this post code value
      int i = 0;
      for (const std::string& messageArg : messageArgs) {
        std::string argStr = "%" + std::to_string(++i);
        size_t argPos = msg.find(argStr);
        if (argPos != std::string::npos) {
          msg.replace(argPos, argStr.length(), messageArg);
        }
      }
    }

    // Get Severity template from message registry
    std::string severity;
    if (message != nullptr) {
      severity = message->messageSeverity;
    }

    // Format entry
    nlohmann::json::object_t bmcLogEntry;
    bmcLogEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
    bmcLogEntry["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Systems", "system", "LogServices", "PostCodes",
        "Entries", postcodeEntryID);
    bmcLogEntry["Name"] = "POST Code Log Entry";
    bmcLogEntry["Id"] = postcodeEntryID;
    bmcLogEntry["Message"] = std::move(msg);
    bmcLogEntry["MessageId"] = "OpenBMC.0.2.BIOSPOSTCode";
    bmcLogEntry["MessageArgs"] = std::move(messageArgs);
    bmcLogEntry["EntryType"] = "Event";
    bmcLogEntry["Severity"] = std::move(severity);
    bmcLogEntry["Created"] = entryTimeStr;
    if (!std::get<std::vector<uint8_t>>(code.second).empty()) {
      bmcLogEntry["AdditionalDataURI"] =
          "/redfish/v1/Systems/system/LogServices/PostCodes/Entries/" +
          postcodeEntryID + "/attachment";
    }

    // codeIndex is only specified when querying single entry, return only
    // that entry in this case
    if (codeIndex != 0) {
      aResp->res.jsonValue.update(bmcLogEntry);
      return true;
    }

    nlohmann::json& logEntryArray = aResp->res.jsonValue["Members"];
    logEntryArray.push_back(std::move(bmcLogEntry));
  }

  // Return value is always false when querying multiple entries
  return false;
}

static void getPostCodeForEntry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                                const std::string& entryId) {
  uint16_t bootIndex = 0;
  uint64_t codeIndex = 0;
  if (!parsePostCode(entryId, codeIndex, bootIndex)) {
    // Requested ID was not found
    messages::resourceNotFound(aResp->res, "LogEntry", entryId);
    return;
  }

  if (bootIndex == 0 || codeIndex == 0) {
    // 0 is an invalid index
    messages::resourceNotFound(aResp->res, "LogEntry", entryId);
    return;
  }

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      [aResp, entryId, bootIndex, codeIndex](
          const boost::system::error_code& ec,
          const boost::container::flat_map<
              uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>& postcode) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS POST CODE PostCode response error";
          messages::internalError(aResp->res);
          return;
        }

        if (postcode.empty()) {
          messages::resourceNotFound(aResp->res, "LogEntry", entryId);
          return;
        }

        if (!fillPostCodeEntry(aResp, postcode, bootIndex, codeIndex)) {
          messages::resourceNotFound(aResp->res, "LogEntry", entryId);
          return;
        }
      },
      "xyz.openbmc_project.State.Boot.PostCode0",
      "/xyz/openbmc_project/State/Boot/PostCode0",
      "xyz.openbmc_project.State.Boot.PostCode", "GetPostCodesWithTimeStamp",
      bootIndex);
}

static void getPostCodeForBoot(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
                               const uint16_t bootIndex,
                               const uint16_t bootCount,
                               const uint64_t entryCount, size_t skip,
                               size_t top) {
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      [aResp, bootIndex, bootCount, entryCount, skip, top](
          const boost::system::error_code& ec,
          const boost::container::flat_map<
              uint64_t, std::tuple<uint64_t, std::vector<uint8_t>>>& postcode) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS POST CODE PostCode response error";
          messages::internalError(aResp->res);
          return;
        }

        uint64_t endCount = entryCount;
        if (!postcode.empty()) {
          endCount = entryCount + postcode.size();
          if (skip < endCount && (top + skip) > entryCount) {
            uint64_t thisBootSkip =
                std::max(static_cast<uint64_t>(skip), entryCount) - entryCount;
            uint64_t thisBootTop =
                std::min(static_cast<uint64_t>(top + skip), endCount) -
                entryCount;

            fillPostCodeEntry(aResp, postcode, bootIndex, 0, thisBootSkip,
                              thisBootTop);
          }
          aResp->res.jsonValue["Members@odata.count"] = endCount;
        }

        // continue to previous bootIndex
        if (bootIndex < bootCount) {
          getPostCodeForBoot(aResp, static_cast<uint16_t>(bootIndex + 1),
                             bootCount, endCount, skip, top);
        } else if (skip + top < endCount) {
          aResp->res.jsonValue["Members@odata.nextLink"] =
              "/redfish/v1/Systems/system/LogServices/PostCodes/"
              "Entries?$skip=" +
              std::to_string(skip + top);
        }
      },
      "xyz.openbmc_project.State.Boot.PostCode0",
      "/xyz/openbmc_project/State/Boot/PostCode0",
      "xyz.openbmc_project.State.Boot.PostCode", "GetPostCodesWithTimeStamp",
      bootIndex);
}

static void getCurrentBootNumber(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, size_t skip, size_t top) {
  uint64_t entryCount = 0;
  managedStore::ManagedObjectStoreContext requestContext(aResp);
  dbus_utils::getProperty<uint16_t>(
      "xyz.openbmc_project.State.Boot.PostCode0",
      "/xyz/openbmc_project/State/Boot/PostCode0",
      "xyz.openbmc_project.State.Boot.PostCode", "CurrentBootCycleCount",
      requestContext,
      [aResp, entryCount, skip, top](const boost::system::error_code& ec,
                                     const uint16_t bootCount) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
          messages::internalError(aResp->res);
          return;
        }
        getPostCodeForBoot(aResp, 1, bootCount, entryCount, skip, top);
      });
}

inline void handleGetPostCodesEntryCollection(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  query_param::QueryCapabilities capabilities = {
      .canDelegateTop = true,
      .canDelegateSkip = true,
  };
  query_param::Query delegatedQuery;
  if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
                                                delegatedQuery, capabilities)) {
    return;
  }

  if (systemName != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", systemName);
    return;
  }
  asyncResp->res.jsonValue["@odata.type"] =
      "#LogEntryCollection.LogEntryCollection";
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/system/LogServices/PostCodes/Entries";
  asyncResp->res.jsonValue["Name"] = "BIOS POST Code Log Entries";
  asyncResp->res.jsonValue["Description"] =
      "Collection of POST Code Log Entries";
  asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
  asyncResp->res.jsonValue["Members@odata.count"] = 0;
  size_t skip = delegatedQuery.skip.value_or(0);
  size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);
  getCurrentBootNumber(asyncResp, skip, top);
}

void requestRoutesPostCodesEntryCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/")
      .privileges(redfish::privileges::getLogEntryCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetPostCodesEntryCollection, std::ref(app)));
}

inline void handleGetPostCodesEntryAdditionalData(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& postCodeID) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  if (http_helpers::isContentTypeAllowed(req.getHeaderValue("Accept"),
                                         http_helpers::ContentType::OctetStream,
                                         true)) {
    asyncResp->res.result(boost::beast::http::status::bad_request);
    return;
  }
  if (systemName != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", systemName);
    return;
  }

  uint64_t currentValue = 0;
  uint16_t index = 0;
  if (!parsePostCode(postCodeID, currentValue, index)) {
    messages::resourceNotFound(asyncResp->res, "LogEntry", postCodeID);
    return;
  }

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp, postCodeID, currentValue](
          const boost::system::error_code& ec,
          const std::vector<std::tuple<uint64_t, std::vector<uint8_t>>>&
              postcodes) {
        if (ec.value() == EBADR) {
          messages::resourceNotFound(asyncResp->res, "LogEntry", postCodeID);
          return;
        }
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
          messages::internalError(asyncResp->res);
          return;
        }

        size_t value = static_cast<size_t>(currentValue) - 1;
        if (value == std::string::npos || postcodes.size() < currentValue) {
          BMCWEB_LOG_WARNING << "Wrong currentValue value";
          messages::resourceNotFound(asyncResp->res, "LogEntry", postCodeID);
          return;
        }

        const auto& [tID, c] = postcodes[value];
        if (c.empty()) {
          BMCWEB_LOG_WARNING << "No found post code data";
          messages::resourceNotFound(asyncResp->res, "LogEntry", postCodeID);
          return;
        }
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
        const char* d = reinterpret_cast<const char*>(c.data());
        std::string_view strData(d, c.size());

        asyncResp->res.addHeader(boost::beast::http::field::content_type,
                                 "application/octet-stream");
        asyncResp->res.addHeader(
            boost::beast::http::field::content_transfer_encoding, "Base64");
        asyncResp->res.body() = crow::utility::base64encode(strData);
      },
      "xyz.openbmc_project.State.Boot.PostCode0",
      "/xyz/openbmc_project/State/Boot/PostCode0",
      "xyz.openbmc_project.State.Boot.PostCode", "GetPostCodes", index);
}

void requestRoutesPostCodesEntryAdditionalData(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/<str>/"
               "attachment/")
      .privileges(redfish::privileges::getLogEntry)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleGetPostCodesEntryAdditionalData, std::ref(app)));
}

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

  getPostCodeForEntry(asyncResp, targetID);
}

void requestRoutesPostCodesEntry(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/<str>/")
      .privileges(redfish::privileges::getLogEntry)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleGetPostCodesEntry, std::ref(app)));
}

static void handleBootTimeLogServiceGet(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_1_0.LogService";
  asyncResp->res.jsonValue["Name"] = "Boot Time Log Service";
  asyncResp->res.jsonValue["Description"] = "Boot Time Log Service";
  asyncResp->res.jsonValue["Id"] = "BootTime";
  asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
  asyncResp->res.jsonValue["LogEntryType"] = "Multiple";

  std::pair<std::string, std::string> redfishDateTimeOffset =
      redfish::time_utils::getDateTimeOffsetNow();
  asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
  asyncResp->res.jsonValue["DateTimeLocalOffset"] =
      redfishDateTimeOffset.second;
}

void handleSystemBootTimeLogServiceGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  // Only for single host
  if (systemName != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", systemName);
    return;
  }
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/" + systemName + "/LogServices/BootTime";
  asyncResp->res.jsonValue["Entries"]["@odata.id"] =
      "/redfish/v1/Systems/" + systemName + "/LogServices/BootTime/Entries";
  handleBootTimeLogServiceGet(asyncResp);
}

void handleManagerBootTimeLogServiceGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Managers/bmc/LogServices/BootTime";
  asyncResp->res.jsonValue["Entries"]["@odata.id"] =
      "/redfish/v1/Managers/bmc/LogServices/BootTime/Entries";
  handleBootTimeLogServiceGet(asyncResp);
}

void requestRoutesBootTimeLogService(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/BootTime/")
      .privileges(redfish::privileges::getLogService)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleSystemBootTimeLogServiceGet, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/BootTime/")
      .privileges(redfish::privileges::getLogService)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleManagerBootTimeLogServiceGet, std::ref(app)));
}

inline static std::string generateBootTimeLogId(
    BootTimeDataType diagnosticsDataType, const size_t index) {
  return bootTimeDataTypeToString(diagnosticsDataType) + std::to_string(index);
}

static std::shared_ptr<nlohmann::json::object_t> makeBootTimeLogEntry(
    BootTimeDataType diagnosticsDataType,
    const nlohmann::json::object_t& diagnosticDataJson, const size_t index,
    const std::string& parentODataId) {
  nlohmann::json::object_t logEntry;
  const std::string id = generateBootTimeLogId(diagnosticsDataType, index);
  // required properties start
  logEntry["@odata.id"] = parentODataId + "/" + id;
  logEntry["@odata.type"] = "#LogEntry.v1_15_0.LogEntry";
  logEntry["Name"] = "Boot Time Log Entry";
  logEntry["Id"] = id;
  logEntry["EntryType"] = "Oem";
  // required properties end
  logEntry["OEMDiagnosticDataType"] =
      bootTimeDataTypeToString(diagnosticsDataType);
  std::string jsonStr = nlohmann::json(diagnosticDataJson).dump();
  logEntry["Message"] = jsonStr;
  const std::string base64DiagnosticData = crow::utility::base64encode(jsonStr);
  logEntry["DiagnosticData"] = base64DiagnosticData;
  return std::make_shared<nlohmann::json::object_t>(logEntry);
}

static void getBootTimeCheckpointLogEntries(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, const std::string& host,
    const std::shared_ptr<const std::string>& parentODataId,
    const std::shared_ptr<size_t>& specificIndex,
    const std::function<void(const nlohmann::json& logEntryArray)>&
        successCallback) {
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      [aResp, parentODataId, specificIndex, successCb{successCallback}](
          const boost::system::error_code& ec,
          const std::vector<BootTimeCheckpoint>& checkpoints) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS Boot Time checkpoints response error";
          messages::internalError(aResp->res);
          return;
        }
        std::span<const BootTimeCheckpoint> filteredCheckpoints;
        if (specificIndex != nullptr) {
          const size_t index = *specificIndex;
          if (index >= checkpoints.size()) {
            messages::resourceNotFound(
                aResp->res, "LogEntry",
                generateBootTimeLogId(BootTimeDataType::CHECKPOINT, index));
            return;
          }
          filteredCheckpoints = std::span<const BootTimeCheckpoint>(
              std::next(checkpoints.begin(), static_cast<int>(index)),
              std::next(checkpoints.begin(), static_cast<int>(index + 1)));
        } else {
          filteredCheckpoints =
              std::span<const BootTimeCheckpoint>(checkpoints);
        }
        nlohmann::json logEntryArray = nlohmann::json::array();
        size_t currentIndex = specificIndex == nullptr ? 0 : *specificIndex;
        for (const BootTimeCheckpoint& checkpoint : filteredCheckpoints) {
          const auto [name, wallTime, monoTime] = checkpoint;
          nlohmann::json::object_t diagnosticDataJson;
          diagnosticDataJson["Name"] = name;
          diagnosticDataJson["WallTimeMs"] = wallTime;
          diagnosticDataJson["MonoTimeMs"] = monoTime;
          try {
            std::shared_ptr<nlohmann::json::object_t> logEntry =
                makeBootTimeLogEntry(BootTimeDataType::CHECKPOINT,
                                     diagnosticDataJson, currentIndex,
                                     *parentODataId);
            logEntryArray.push_back(std::move(*logEntry));
          } catch (...) {
            // May face error while parsing data to json or to base64
            BMCWEB_LOG_DEBUG
                << "Error while making Boot time log entry for Checkpoint"
                << std::to_string(currentIndex);
            messages::internalError(aResp->res);
            return;
          }
          currentIndex++;
        }
        successCb(logEntryArray);
      },
      "com.google.gbmc.boot_time_monitor",
      "/xyz/openbmc_project/time/boot/" + host,
      "xyz.openbmc_project.Time.Boot.Checkpoint", "GetCheckpointList");
}

static void getBootTimeDurationLogEntries(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, const std::string& host,
    const std::shared_ptr<const std::string>& parentODataId,
    const std::shared_ptr<size_t>& specificIndex,
    const std::function<void(const nlohmann::json& logEntryArray)>&
        successCallback) {
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      [aResp, parentODataId, specificIndex, successCb{successCallback}](
          const boost::system::error_code& ec,
          const std::vector<BootTimeDuration>& durations) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS Boot Time durations response error";
          messages::internalError(aResp->res);
          return;
        }
        std::span<const BootTimeDuration> filteredDurations;
        if (specificIndex != nullptr) {
          const size_t index = *specificIndex;
          if (index >= durations.size()) {
            messages::resourceNotFound(
                aResp->res, "LogEntry",
                generateBootTimeLogId(BootTimeDataType::DURATION, index));
            return;
          }
          filteredDurations = std::span<const BootTimeDuration>(
              std::next(durations.begin(), static_cast<int>(index)),
              std::next(durations.begin(), static_cast<int>(index + 1)));
        } else {
          filteredDurations = std::span<const BootTimeDuration>(durations);
        }
        nlohmann::json logEntryArray = nlohmann::json::array();
        size_t currentIndex = specificIndex == nullptr ? 0 : *specificIndex;
        for (const BootTimeDuration& duration : filteredDurations) {
          nlohmann::json::object_t diagnosticDataJson;
          const auto [name, durationMs] = duration;
          diagnosticDataJson["Name"] = name;
          diagnosticDataJson["DurationMs"] = durationMs;
          try {
            std::shared_ptr<nlohmann::json::object_t> logEntry =
                makeBootTimeLogEntry(BootTimeDataType::DURATION,
                                     diagnosticDataJson, currentIndex,
                                     *parentODataId);
            logEntryArray.push_back(std::move(*logEntry));
          } catch (...) {
            // May face error while parsing data to json or to base64
            BMCWEB_LOG_DEBUG
                << "Error while making Boot time log entry for Duration"
                << std::to_string(currentIndex);
            messages::internalError(aResp->res);
            return;
          }
          currentIndex++;
        }
        successCb(logEntryArray);
      },
      "com.google.gbmc.boot_time_monitor",
      "/xyz/openbmc_project/time/boot/" + host,
      "xyz.openbmc_project.Time.Boot.Duration", "GetAdditionalDurations");
}

static void getBootTimeStatisticLogEntry(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp, const std::string& host,
    const std::shared_ptr<const std::string>& parentODataId,
    const std::function<void(const nlohmann::json& logEntryArray)>&
        successCallback) {
  managedStore::ManagedObjectStoreContext requestContext(aResp);
  dbus_utils::getProperty<bool>(
      "com.google.gbmc.boot_time_monitor",
      "/xyz/openbmc_project/time/boot/" + host,
      "xyz.openbmc_project.Time.Boot.Statistic", "IsRebooting", requestContext,
      [aResp, parentODataId, successCb{successCallback}](
          const boost::system::error_code& ec, const bool rebooting) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS Boot Time rebooting response error" << ec;
          messages::internalError(aResp->res);
          return;
        }
        nlohmann::json logEntryArray = nlohmann::json::array();
        nlohmann::json::object_t diagnosticDataJson;
        diagnosticDataJson["IsRebooting"] = rebooting;
        try {
          std::shared_ptr<nlohmann::json::object_t> logEntry =
              makeBootTimeLogEntry(BootTimeDataType::STATISTIC,
                                   diagnosticDataJson, 0, *parentODataId);
          logEntryArray.push_back(std::move(*logEntry));
        } catch (...) {
          // May face error while parsing data to json or to base64
          BMCWEB_LOG_DEBUG
              << "Error while making Boot time log entry for Statistic0";
          messages::internalError(aResp->res);
          return;
        }
        successCb(logEntryArray);
      });
}

inline void addBootLogEntriesToRespAndCount(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const nlohmann::json& logEntryArray) {
  for (auto entry : logEntryArray) {
    asyncResp->res.jsonValue["Members"].push_back(std::move(entry));
  }
  asyncResp->res.jsonValue["Members@odata.count"] =
      asyncResp->res.jsonValue["Members"].size();
}

inline void handleBootTimeLogsEntryCollectionGet(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& host) {
  asyncResp->res.jsonValue["@odata.type"] =
      "#LogEntryCollection.LogEntryCollection";
  asyncResp->res.jsonValue["Name"] = "Boot Time Log Entries";
  asyncResp->res.jsonValue["Description"] =
      "Collection of Boot time Log Entries with checkpoints and duration";

  std::shared_ptr<const std::string> parentId =
      std::make_shared<const std::string>(
          asyncResp->res.jsonValue["@odata.id"]);
  asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
  getBootTimeCheckpointLogEntries(
      asyncResp, host, parentId, nullptr,
      std::bind_front(addBootLogEntriesToRespAndCount, asyncResp));
  getBootTimeDurationLogEntries(
      asyncResp, host, parentId, nullptr,
      std::bind_front(addBootLogEntriesToRespAndCount, asyncResp));
  getBootTimeStatisticLogEntry(
      asyncResp, host, parentId,
      std::bind_front(addBootLogEntriesToRespAndCount, asyncResp));
}

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

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

  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/" + systemName + "/LogServices/BootTime/Entries";
  handleBootTimeLogsEntryCollectionGet(asyncResp, "host0");
}

void handleManagerBootTimeLogsEntryCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Managers/bmc/LogServices/BootTime/Entries";
  handleBootTimeLogsEntryCollectionGet(asyncResp, "bmc");
}

void requestRoutesBootTimeLogEntryCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/BootTime/Entries/")
      .privileges(redfish::privileges::getLogEntryCollection)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleSystemBootTimeLogsEntryCollectionGet, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/BootTime/Entries/")
      .privileges(redfish::privileges::getLogEntryCollection)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleManagerBootTimeLogsEntryCollectionGet, std::ref(app)));
}

static bool parseBootTimeLogEntryId(const std::string& entryId,
                                    BootTimeDataType& dataType, size_t& index) {
  size_t typeIndex = 0;
  for (const std::string_view type : bootTimeDataTypeString) {
    if (entryId.starts_with(type.data())) {
      // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
      auto [_, ec] = std::from_chars(entryId.c_str() + type.length(),
                                     entryId.c_str() + entryId.length(), index);
      // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
      // calling std::errc without any argument means successful parse
      if (ec != std::errc()) {
        return false;
      }
      dataType = static_cast<BootTimeDataType>(typeIndex);
      return (dataType != BootTimeDataType::STATISTIC || index == 0);
    }
    typeIndex++;
  }
  return false;
}

inline void mergeBootLogEntryToResp(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::shared_ptr<const std::string>& entryId,
    const nlohmann::json& logEntryArray) {
  if (asyncResp->res.jsonValue.contains("error")) {
    return;
  }
  if (logEntryArray.empty()) {
    messages::resourceNotFound(asyncResp->res, "LogEntry", *entryId);
    return;
  }
  asyncResp->res.jsonValue.merge_patch(logEntryArray[0]);
}

inline void handleBootTimeLogsEntryGet(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& host, const std::string& entryId,
    const std::string& parentODataId) {
  BootTimeDataType dataType = BootTimeDataType::CHECKPOINT;
  size_t index = 0;
  if (!parseBootTimeLogEntryId(entryId, dataType, index)) {
    messages::resourceNotFound(asyncResp->res, "LogEntry", entryId);
    return;
  }
  std::shared_ptr<const std::string> parentId =
      std::make_shared<const std::string>(parentODataId);
  std::shared_ptr<const std::string> entryIdPtr =
      std::make_shared<const std::string>(entryId);
  std::shared_ptr<size_t> indexPt = std::make_shared<size_t>(index);
  if (dataType == BootTimeDataType::CHECKPOINT) {
    getBootTimeCheckpointLogEntries(
        asyncResp, host, parentId, indexPt,
        std::bind_front(mergeBootLogEntryToResp, asyncResp, entryIdPtr));
  } else if (dataType == BootTimeDataType::DURATION) {
    getBootTimeDurationLogEntries(
        asyncResp, host, parentId, indexPt,
        std::bind_front(mergeBootLogEntryToResp, asyncResp, entryIdPtr));
  } else {
    getBootTimeStatisticLogEntry(
        asyncResp, host, parentId,
        std::bind_front(mergeBootLogEntryToResp, asyncResp, entryIdPtr));
  }
}

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

  // only for single host
  if (systemName != "system") {
    messages::resourceNotFound(asyncResp->res, "ComputerSystem", systemName);
    return;
  }
  handleBootTimeLogsEntryGet(
      asyncResp, "host0", entryId,
      "/redfish/v1/Systems/" + systemName + "/LogServices/BootTime/Entries");
}
void handleManagerBootTimeLogsEntryGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& entryId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  handleBootTimeLogsEntryGet(
      asyncResp, "bmc", entryId,
      "/redfish/v1/Managers/bmc/LogServices/BootTime/Entries");
}

void requestRoutesBootTimeLogEntry(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/<str>/LogServices/BootTime/Entries/<str>")
      .privileges(redfish::privileges::getLogEntryCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleSystemBootTimeLogsEntryGet, std::ref(app)));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Managers/bmc/LogServices/BootTime/Entries/<str>")
      .privileges(redfish::privileges::getLogEntryCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleManagerBootTimeLogsEntryGet, std::ref(app)));
}

void handlePPRServiceGet(App& app, const crow::Request& req,
                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  // Copy over the static data to include the entries added by SubRoute
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair";
  asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
  asyncResp->res.jsonValue["Name"] = "Open BMC Oem PPR Service";
  asyncResp->res.jsonValue["Description"] = "Oem Post Package Repair Service";
  asyncResp->res.jsonValue["Id"] = "Oem ppr";
  asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
  asyncResp->res.jsonValue["Members"] = {
      {{"@odata.id",
        "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair/"
        "Config"}},
      {{"@odata.id",
        "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair/"
        "Status"}},
  };
  asyncResp->res.jsonValue["Members@odata.count"] =
      asyncResp->res.jsonValue["Members"].size();
  asyncResp->res.jsonValue["Actions"] = {
      {"#PostPackageRepair.SetRepairConfig",
       {{"target",
         "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair/"
         "Actions/PostPackageRepair.SetRepairConfig"}}},
      {"#PostPackageRepair.SetRepairData",
       {{"target",
         "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair/"
         "Actions/PostPackageRepair.SetRepairData"}}}};
}

void getPostPackageRepairStatus(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      requestContext.GetStrand(),
      [asyncResp](
          const boost::system::error_code& ec,
          const std::vector<std::tuple<uint16_t, uint16_t, uint16_t, uint16_t,
                                       std::vector<uint16_t>>>&
              postpackagerepairstatus) {
        if (ec) {
          BMCWEB_LOG_ERROR
              << "DBUS response error in getPostPackageRepairStatus"
              << ec.message();
          messages::internalError(asyncResp->res);
          return;
        }

        BMCWEB_LOG_DEBUG << "D-Bus getPostPackageRepairStatus success size : "
                         << postpackagerepairstatus.size();

        nlohmann::json pprDataOut = nlohmann::json::array();
        int count = 0;
        for (const auto& resolveList : postpackagerepairstatus) {
          BMCWEB_LOG_INFO << "Testing : " << std::get<0>(resolveList);
          uint16_t repairEntryNum = std::get<0>(resolveList);
          uint16_t repairType = std::get<1>(resolveList);
          uint16_t socNum = std::get<2>(resolveList);
          uint16_t repairResult = std::get<3>(resolveList);
          std::vector<uint16_t> payload = std::get<4>(resolveList);

          nlohmann::json jsonPpr = {{"repairEntryNum", repairEntryNum},
                                    {"repairType", repairType},
                                    {"socNum", socNum},
                                    {"repairResult", repairResult},
                                    {"payload", payload}};
          pprDataOut.push_back(jsonPpr);
          count++;
        }

        asyncResp->res.jsonValue["Members"] = pprDataOut;
        asyncResp->res.jsonValue["Members@odata.count"] = count;
      },
      pprFileObject, pprFilePath, pprFileInterface,
      "getPostPackageRepairStatus");
}

void handlePPRStatusGet(App& app, const crow::Request& req,
                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  asyncResp->res.jsonValue["@odata.type"] = "#LogEntry.v1_4_0.LogEntry";
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair/"
      "Status";
  asyncResp->res.jsonValue["Name"] = "Post Package Repair Entries";
  asyncResp->res.jsonValue["Description"] =
      "Collection of Post Package Repair Entries";
  asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
  asyncResp->res.jsonValue["Members@odata.count"] = 0;

  getPostPackageRepairStatus(asyncResp);
}

void setPostPackageRepairData(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const uint16_t Index,
    const uint16_t repairEntryNum, const uint16_t repairType,
    const uint16_t socNum, std::vector<uint16_t>& payload) {
  std::optional<bool> RecordAdd = true;
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      requestContext.GetStrand(),
      [asyncResp, RecordAdd, Index, requestContext](
          const boost::system::error_code& ec, const bool& recordAdd) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBUS POST Package Repair Record Add error";
          messages::internalError(asyncResp->res);
          return;
        }
        BMCWEB_LOG_DEBUG << "DBUS POST Package Repair Record Added : "
                         << int(recordAdd);

        managedStore::GetManagedObjectStore()->setProperty(
            pprFileObject, pprFilePath, pprFileInterface, "RecordAdd",
            *RecordAdd,
            [asyncResp, Index,
             requestContext](const boost::system::error_code& ec) {
              if (ec) {
                BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
                messages::internalError(asyncResp->res);
                return;
              }
              BMCWEB_LOG_INFO << "D-Bus Record Add success";

              managedStore::GetManagedObjectStore()
                  ->PostDbusCallToIoContextThreadSafe(
                      requestContext.GetStrand(),
                      [asyncResp](const boost::system::error_code& ec,
                                  const uint32_t& startRuntimeRepair) {
                        if (ec) {
                          BMCWEB_LOG_ERROR << "DBUS start Runtime Repair error";
                          messages::internalError(asyncResp->res);
                          return;
                        }
                        BMCWEB_LOG_INFO
                            << "DBUS success start Runtime Repair : "
                            << startRuntimeRepair;
                      },
                      pprFileObject, pprFilePath, pprFileInterface,
                      "startRuntimeRepair", Index);
            });
      },
      pprFileObject, pprFilePath, pprFileInterface, "setPostPackageRepairData",
      repairEntryNum, repairType, socNum, payload);
}

static bool& getOobPprEnable() {
  static bool oobPprEnable = false;
  return oobPprEnable;
}

void handlePPRFilePost(App& app, const crow::Request& req,
                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  uint16_t RepairType = 0;
  uint16_t RepairEntryNum = 0;
  uint16_t SocNum = 0;
  uint16_t Index = 0;
  uint16_t RuntimeIndex = 0;
  nlohmann::json jsonRequest;
  bool& oobPprEnable = getOobPprEnable();

  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  dbus_utils::getProperty<bool>(
      pprFileObject, pprFilePath, pprFileInterface, "oobPprEnable",
      requestContext,
      [asyncResp, &oobPprEnable](const boost::system::error_code& ec,
                                 const bool oobPpr) {
        if (ec) {
          BMCWEB_LOG_ERROR << "D-Bus responses error for OOB PPR Enable: "
                           << ec;
          messages::internalError(asyncResp->res);
          return;
        }
        oobPprEnable = oobPpr;
      });

  if (!oobPprEnable) {
    BMCWEB_LOG_ERROR << "Error: OOB PPR is Not Enabled";
    messages::internalError(asyncResp->res);
    return;
  }

  if (!json_util::processJsonFromRequest(asyncResp->res, req, jsonRequest)) {
    BMCWEB_LOG_ERROR << "Error: Json value not readable";
    messages::malformedJSON(asyncResp->res);
    return;
  }

  for (const auto& el : jsonRequest["pprDataIn"].items()) {
    std::vector<uint16_t> Payload;

    BMCWEB_LOG_DEBUG << "Key " << el.key();
    BMCWEB_LOG_DEBUG << "value " << el.value();

    if (!json_util::readJson(el.value(), asyncResp->res, "RepairType",
                             RepairType, "RepairEntryNum", RepairEntryNum,
                             "SocNum", SocNum, "Payload", Payload)) {
      BMCWEB_LOG_ERROR << "Error: Issue with Json value read";
      messages::malformedJSON(asyncResp->res);
      return;
    }

    if ((RepairType & kPPRTypeBoottimeMask) == 0) {
      RuntimeIndex++;
      if (RuntimeIndex > kMaxRuntimePPRCount) {
        BMCWEB_LOG_ERROR << "Error: Exceed Runtime PPR Max Entry of "
                         << kMaxRuntimePPRCount;
        messages::invalidObject(asyncResp->res,
                                "Runtime PPR entries exceed PPR Max Entry of " +
                                    std::to_string(kMaxRuntimePPRCount));
        return;
      }
    }

    setPostPackageRepairData(asyncResp, Index, RepairEntryNum, RepairType,
                             SocNum, Payload);
    Index++;
  }

  messages::success(asyncResp->res);
}

void getPostPackageRepairConfig(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  managedStore::ManagedObjectStoreContext requestContext(aResp);
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      requestContext.GetStrand(),
      [aResp](const boost::system::error_code& ec,
              const std::vector<uint16_t>& postpackagerepairconfig) {
        if (ec) {
          BMCWEB_LOG_ERROR
              << "DBUS response error in getPostPackageRepairConfig"
              << ec.message();
          messages::internalError(aResp->res);
          return;
        }

        nlohmann::json pprConfig = nlohmann::json::array();

        bool RtToBt = false;
        bool BtSetToHard = false;
        bool& oobPprEnable = getOobPprEnable();

        oobPprEnable = (postpackagerepairconfig[0] != 0);
        RtToBt = (postpackagerepairconfig[1] != 0);
        BtSetToHard = (postpackagerepairconfig[2] != 0);

        nlohmann::json jsonPpr = {{"OobPprEnable", oobPprEnable},
                                  {"autoScheduleRtAsBtPpr", RtToBt},
                                  {"autoScheduleBtAsHard", BtSetToHard}};
        pprConfig.push_back(jsonPpr);

        aResp->res.jsonValue["Members"] = pprConfig;
        aResp->res.jsonValue["Members@odata.count"] = 1;
      },
      pprFileObject, pprFilePath, pprFileInterface,
      "getPostPackageRepairConfig");
}

void setPostPackageRepairConfig(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const uint16_t& flag,
    const bool& data) {
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      requestContext.GetStrand(),
      [asyncResp](const boost::system::error_code& ec, const bool& result) {
        if (ec) {
          BMCWEB_LOG_ERROR
              << "DBUS response error in setPostPackageRepairConfig"
              << ec.message();
          messages::internalError(asyncResp->res);
          return;
        }
        BMCWEB_LOG_DEBUG << "DBUS POST Package Repair Config Changed : "
                         << int(result);
      },
      pprFileObject, pprFilePath, pprFileInterface,
      "setPostPackageRepairConfig", flag, data);
}

void handlePPRConfigGet(App& app, const crow::Request& req,
                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  asyncResp->res.jsonValue["@odata.type"] = "#LogEntry.v1_4_0.LogEntry";
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair/"
      "Config";
  asyncResp->res.jsonValue["Name"] = "Post Package Repair Config";
  asyncResp->res.jsonValue["Description"] = "Post Package Repair Configuration";
  asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
  asyncResp->res.jsonValue["Members@odata.count"] = 0;

  getPostPackageRepairConfig(asyncResp);
}

void handlePPRConfigPost(App& app, const crow::Request& req,
                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  std::optional<bool> BtSetToHard;
  std::optional<bool> RtToBt;
  uint16_t flag = 0;
  bool data = false;
  nlohmann::json jsonRequest;

  if (!json_util::processJsonFromRequest(asyncResp->res, req, jsonRequest)) {
    BMCWEB_LOG_ERROR << "Error: Json value not readable";
    messages::malformedJSON(asyncResp->res);
    return;
  }

  if (!json_util::readJson(jsonRequest, asyncResp->res, "autoScheduleBtAsHard",
                           BtSetToHard, "autoScheduleRtAsBtPpr", RtToBt)) {
    return;
  }
  if (BtSetToHard) {
    flag = kBtSetToHardMask;
    data = BtSetToHard.value();
  }
  if (RtToBt) {
    flag = kRtToBtMask;
    data = RtToBt.value();
  }
  if (flag == 0) {
    std::cout << "PPR Config Error: post command, Param not found\n";
    return;
  }
  setPostPackageRepairConfig(asyncResp, flag, data);
  messages::success(asyncResp->res);
}

void requestRoutesPPRService(App& app) {
  BMCWEB_ROUTE(
      app, "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair/")
      .privileges({{"ConfigureComponents"}})
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handlePPRServiceGet, std::ref(app)));
}

void requestRoutesPPRStatus(App& app) {
  BMCWEB_ROUTE(
      app,
      "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair/Status")
      .privileges({{"ConfigureComponents"}})
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handlePPRStatusGet, std::ref(app)));
}

void requestRoutesPPRFile(App& app) {
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/system/LogServices/Oem/Amd/"
               "PostPackageRepair/Actions/PostPackageRepair.SetRepairData")
      .privileges({{"ConfigureComponents"}})
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handlePPRFilePost, std::ref(app)));
}

void requestRoutesPPRConfig(App& app) {
  BMCWEB_ROUTE(
      app,
      "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair/Config")
      .privileges({{"ConfigureComponents"}})
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handlePPRConfigGet, std::ref(app)));
  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/system/LogServices/Oem/Amd/"
               "PostPackageRepair/Actions/PostPackageRepair.SetRepairConfig")
      .privileges({{"ConfigureManager"}})
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handlePPRConfigPost, std::ref(app)));
}

}  // namespace redfish
