#include "log_services.hpp"

#include "bmcweb_config.h"

#include "app.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "external_storer.hpp"
#include "generated/enums/log_entry.hpp"
#include "gzfile.hpp"
#include "http_utility.hpp"
#include "human_sort.hpp"
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "query.hpp"
#include "redfish_util.hpp"
#include "registries.hpp"
#include "registries/base_message_registry.hpp"
#include "registries/openbmc_message_registry.hpp"
#include "registries/privilege_registry.hpp"
#include "task.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/system_utils.hpp"
#include "utils/time_utils.hpp"

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

#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/beast/core/detail/base64.hpp>
#include <boost/beast/http/verb.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/system/linux_error.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/message/types.hpp>
#include <sdbusplus/unpack_properties.hpp>

#include <array>
#include <charconv>
#include <cstdint>
#include <filesystem>
#include <functional>
#include <optional>
#include <span>
#include <string_view>
#include <unordered_map>
#include <utility>
#include <variant>

#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 getJournalMetadata(sd_journal* journal,
                                     std::string_view field, const int& base,
                                     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;
    }
    contents = strtol(metadata.data(), nullptr, base);
    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";
                }
                // entryType must be of CPER or CrashDump or else accessing
                // thisEntry["AdditionalDataURI"] becomes undefined behavior
                else
                {
                    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";
                }
                // entryType must be of CPER or CrashDump or else accessing
                // thisEntry["AdditionalDataURI"] becomes undefined behavior
                else
                {
                    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/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 = getJournalMetadata(journal, "PRIORITY", 10, 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/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/PostPackageRepair/"
         "Config"},
        {"@odata.id",
         "/redfish/v1/Systems/system/LogServices/PostPackageRepair/"
         "Status"},
    };
    asyncResp->res.jsonValue["Members@odata.count"] =
        asyncResp->res.jsonValue["Members"].size();
    asyncResp->res.jsonValue["Actions"] = {
        {"#LogService.pprStatus",
         {{"target", "/redfish/v1/Systems/system/LogServices/PostPackageRepair/"
                     "Status"}}},
        {"#LogService.pprFile",
         {{"target", "/redfish/v1/Systems/system/LogServices/PostPackageRepair/"
                     "RepairData"}}}};
}

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");

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

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/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 handlePPRFilePatch(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");

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

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/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 handlePPRConfigPatch(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: patch 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/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/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/PostPackageRepair/RepairData")
        .privileges({{"ConfigureComponents"}})
        .methods(boost::beast::http::verb::patch)(
            std::bind_front(handlePPRFilePatch, std::ref(app)));
}

void requestRoutesPPRConfig(App& app)
{
    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/system/LogServices/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/PostPackageRepair/Config")
        .privileges({{"ConfigureManager"}})
        .methods(boost::beast::http::verb::patch)(
            std::bind_front(handlePPRConfigPatch, std::ref(app)));
}

} // namespace redfish
