#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 "dbus_utils.hpp"
#include "system_utils.hpp"
#include "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/Oem/Amd/PostPackageRepair";
        logServiceArray.push_back(std::move(ppr));
#endif

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return true;
}

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

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

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

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

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

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

inline void handleSystemHostLoggerCollection(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemPath, const query_param::Query& delegatedQuery)
{
    // If the systemPath is empty, then the system is single host
    bool multiHost = !systemPath.empty();

    // Default systemName is system and change if system is multi-host
    std::string systemName = "system";
    if (multiHost)
    {
        systemName = sdbusplus::message::object_path(systemPath).filename();
    }

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

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

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

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

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

inline void handleSystemHostLoggerLogEntry(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemPath, const std::string& param)
{
    // If the systemPath is empty, then the system is single host
    bool multiHost = !systemPath.empty();

    // Default systemName is system and change if system is multi-host
    std::string systemName = "system";
    if (multiHost)
    {
        systemName = sdbusplus::message::object_path(systemPath).filename();
    }

    const std::string& targetID = param;

    uint64_t idInt = 0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // Get the severity from the PRIORITY field
    int64_t severity = 8; // Default to an invalid priority
    ret = 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/Oem/Amd/PostPackageRepair";
    asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
    asyncResp->res.jsonValue["Name"] = "Open BMC Oem PPR Service";
    asyncResp->res.jsonValue["Description"] = "Oem Post Package Repair Service";
    asyncResp->res.jsonValue["Id"] = "Oem ppr";
    asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
    asyncResp->res.jsonValue["Members"] = {
        {{"@odata.id",
          "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair/"
          "Config"}},
        {{"@odata.id",
          "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair/"
          "Status"}},
    };
    asyncResp->res.jsonValue["Members@odata.count"] =
        asyncResp->res.jsonValue["Members"].size();
    asyncResp->res.jsonValue["Actions"] = {
        {"#PostPackageRepair.SetRepairConfig",
         {{"target",
           "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair/"
           "Actions/PostPackageRepair.SetRepairConfig"}}},
        {"#PostPackageRepair.SetRepairData",
         {{"target",
           "/redfish/v1/Systems/system/LogServices/Oem/Amd/PostPackageRepair/"
           "Actions/PostPackageRepair.SetRepairData"}}}};
}

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

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

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

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

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

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

    getPostPackageRepairStatus(asyncResp);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

void setPostPackageRepairConfig(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const uint16_t& flag,
    const bool& data)
{

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

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

    getPostPackageRepairConfig(asyncResp);
}

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

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

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

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

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

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

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

} // namespace redfish
