#include "log_services.hpp"

#include "bmcweb_config.h"

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

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

#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/beast/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 <filesystem>
#include <functional>
#include <optional>
#include <span>
#include <string_view>
#include <utility>
#include <variant>

namespace redfish
{

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* defaultLogPrefix = "log";

enum class DumpCreationProgress
{
    DUMP_CREATE_SUCCESS,
    DUMP_CREATE_FAILED,
    DUMP_CREATE_INPROGRESS
};

enum class FaultlogType
{
    Crashdump,
    HostCper
};

namespace fs = std::filesystem;

inline std::string translateSeverityDbusToRedfish(const std::string& s)
{
    if ((s == "xyz.openbmc_project.Logging.Entry.Level.Alert") ||
        (s == "xyz.openbmc_project.Logging.Entry.Level.Critical") ||
        (s == "xyz.openbmc_project.Logging.Entry.Level.Emergency") ||
        (s == "xyz.openbmc_project.Logging.Entry.Level.Error"))
    {
        return "Critical";
    }
    if ((s == "xyz.openbmc_project.Logging.Entry.Level.Debug") ||
        (s == "xyz.openbmc_project.Logging.Entry.Level.Informational") ||
        (s == "xyz.openbmc_project.Logging.Entry.Level.Notice"))
    {
        return "OK";
    }
    if (s == "xyz.openbmc_project.Logging.Entry.Level.Warning")
    {
        return "Warning";
    }
    return "";
}

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 std::optional<bool> getProviderNotifyAction(const std::string& notify)
{
    std::optional<bool> notifyAction;
    if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Notify")
    {
        notifyAction = true;
    }
    else if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Inhibit")
    {
        notifyAction = false;
    }

    return notifyAction;
}

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,
                                     long int& 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;
}

static bool getUniqueEntryID(const std::string& logEntry, std::string& entryID,
                             const bool firstEntry = true)
{
    static time_t prevTs = 0;
    static int index = 0;
    if (firstEntry)
    {
        prevTs = 0;
    }

    // Get the entry timestamp
    std::time_t curTs = 0;
    std::tm timeStruct = {};
    std::istringstream entryStream(logEntry);
    if (entryStream >> std::get_time(&timeStruct, "%Y-%m-%dT%H:%M:%S"))
    {
        curTs = std::mktime(&timeStruct);
    }
    // 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;
}

static bool
    getRedfishLogFiles(std::vector<std::filesystem::path>& redfishLogFiles)
{
    static const std::filesystem::path redfishLogDir = "/var/log";
    static const std::string redfishLogFilename = "redfish";

    // Loop through the directory looking for redfish log files
    for (const std::filesystem::directory_entry& dirEnt :
         std::filesystem::directory_iterator(redfishLogDir))
    {
        // If we find a redfish log file, save the path
        std::string filename = dirEnt.path().filename();
        if (filename.starts_with(redfishLogFilename))
        {
            redfishLogFiles.emplace_back(redfishLogDir / filename);
        }
    }
    // As the log files rotate, they are appended with a ".#" that is higher for
    // the older logs. Since we don't expect more than 10 log files, we
    // can just sort the list to get them in order from newest to oldest
    std::sort(redfishLogFiles.begin(), redfishLogFiles.end());

    return !redfishLogFiles.empty();
}

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.Dump.Entry.FaultLog.FaultDataType.Crashdump")
                    {
                        entryType = "Crashdump";
                    }
                    else if (
                        *entryTypePtr ==
                        "xyz.openbmc_project.Dump.Entry.FaultLog.FaultDataType.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;
}

inline void
    getDumpEntryCollection(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                           const Dump& dump)
{
    std::string entriesPath = getDumpEntriesPath(dump);
    if (entriesPath.empty())
    {
        messages::internalError(asyncResp->res);
        return;
    }
    managedStore::ManagedObjectStoreContext context(asyncResp);
    managedStore::managedObjectStore->getManagedObjectsWithContext(
        "xyz.openbmc_project.Dump.Manager", {"/xyz/openbmc_project/dump"},
        context,
        [asyncResp, entriesPath,
         dump](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());
        });

        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;
            }

            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 (primaryLogId.find("/Entries/") != std::string::npos)
                    {
                        // This is for backward compatibility; we can remove it
                        // later.
                        thisEntry["AdditionalDataURI"] =
                            "/redfish/v1/Systems/" + systemPathSegment + "/LogServices/" +
                            primaryLogId;
                    }
                    else
                    {
                        // Will eventually be changed from AdditionalDataURI to
                        // OriginOfCondition Link
                        thisEntry["AdditionalDataURI"] =
                            "/redfish/v1/Systems/" + systemPathSegment + "/LogServices/" +
                            std::string(hostCperLogServiceName) + "/Entries/" +
                            primaryLogId;
                    }
                    thisEntry["OemRecordFormat"] = "CPER";
                }
                else if (entryType == "Crashdump")
                {
                    thisEntry["AdditionalDataURI"] =
                        "/redfish/v1/Systems/" + systemPathSegment + "/LogServices/Crashdump/Entries/" +
                        primaryLogId;
                    thisEntry["OemRecordFormat"] = "Crashdump";
                }

                // 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;
            }
            entriesArray.push_back(std::move(thisEntry));
        }
        asyncResp->res.jsonValue["Members@odata.count"] = entriesArray.size();
    });
}

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::managedObjectStore->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 (primaryLogId.find("/Entries/") != std::string::npos)
                    {
                        // This is for backward compatibility; we can remove it
                        // later.
                        asyncResp->res.jsonValue["AdditionalDataURI"] =
                            "/redfish/v1/Systems/" + systemPathSegment + "/LogServices/" +
                            primaryLogId;
                    }
                    else
                    {
                        // Will eventually be changed from AdditionalDataURI to
                        // OriginOfCondition Link
                        asyncResp->res.jsonValue["AdditionalDataURI"] =
                            "/redfish/v1/Systems/" + systemPathSegment + "/LogServices/" +
                            std::string(hostCperLogServiceName) + "/Entries/" +
                            primaryLogId;
                    }
                    asyncResp->res.jsonValue["OemRecordFormat"] = "CPER";
                }
                else if (entryType == "Crashdump")
                {
                    asyncResp->res.jsonValue["AdditionalDataURI"] =
                        "/redfish/v1/Systems/" + systemPathSegment + "/LogServices/Crashdump/Entries/" +
                        primaryLogId;
                    asyncResp->res.jsonValue["OemRecordFormat"] = "Crashdump";
                }

                // 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;
    }

    crow::connections::systemBus->async_method_call(
        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;
    }

    long long int 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));
    long long int 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;
    }

    crow::connections::systemBus->async_method_call(
        [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");
    }

    crow::connections::systemBus->async_method_call(
        [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;
    }

    crow::connections::systemBus->async_method_call(
        [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_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_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::managedObjectStore->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 (pathStr.find("PostCode") != std::string::npos)
                {
                    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);
    });
}

void requestRoutesEventLogService(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/")
        .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;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }
        asyncResp->res.jsonValue["@odata.id"] =
            "/redfish/v1/Systems/system/LogServices/EventLog";
        asyncResp->res.jsonValue["@odata.type"] =
            "#LogService.v1_1_0.LogService";
        asyncResp->res.jsonValue["Name"] = "Event Log Service";
        asyncResp->res.jsonValue["Description"] = "System Event Log Service";
        asyncResp->res.jsonValue["Id"] = "EventLog";
        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/Systems/system/LogServices/EventLog/Entries";
        asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"] = {

            {"target",
             "/redfish/v1/Systems/system/LogServices/EventLog/Actions/LogService.ClearLog"}};
    });
}

void requestRoutesJournalEventLogClear(App& app)
{
    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/")
        .privileges({{"ConfigureComponents"}})
        .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;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }
        // Clear the EventLog by deleting the log files
        std::vector<std::filesystem::path> redfishLogFiles;
        if (getRedfishLogFiles(redfishLogFiles))
        {
            for (const std::filesystem::path& file : redfishLogFiles)
            {
                std::error_code ec;
                std::filesystem::remove(file, ec);
            }
        }

        // Reload rsyslog so it knows to start new log files
        crow::connections::systemBus->async_method_call(
            [asyncResp](const boost::system::error_code& ec) {
            if (ec)
            {
                BMCWEB_LOG_ERROR << "Failed to reload rsyslog: " << ec;
                messages::internalError(asyncResp->res);
                return;
            }

            messages::success(asyncResp->res);
        },
            "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
            "org.freedesktop.systemd1.Manager", "ReloadUnit", "rsyslog.service",
            "replace");
    });
}

enum class LogParseError
{
    success,
    parseFailed,
    messageIdNotInRegistry,
};

static LogParseError
    fillEventLogEntryJson(const std::string& logEntryID,
                          const std::string& logEntry,
                          nlohmann::json::object_t& logEntryJson)
{
    // The redfish log format is "<Timestamp> <MessageId>,<MessageArgs>"
    // First get the Timestamp
    size_t space = logEntry.find_first_of(' ');
    if (space == std::string::npos)
    {
        return LogParseError::parseFailed;
    }
    std::string timestamp = logEntry.substr(0, space);
    // Then get the log contents
    size_t entryStart = logEntry.find_first_not_of(' ', space);
    if (entryStart == std::string::npos)
    {
        return LogParseError::parseFailed;
    }
    std::string_view entry(logEntry);
    entry.remove_prefix(entryStart);
    // Use split to separate the entry into its fields
    std::vector<std::string> logEntryFields;
    bmcweb::split(logEntryFields, entry, ',');
    // We need at least a MessageId to be valid
    if (logEntryFields.empty())
    {
        return LogParseError::parseFailed;
    }
    std::string& messageID = logEntryFields[0];

    // Get the Message from the MessageRegistry
    const registries::Message* message = registries::getMessage(messageID);

    if (message == nullptr)
    {
        BMCWEB_LOG_WARNING << "Log entry not found in registry: " << logEntry;
        return LogParseError::messageIdNotInRegistry;
    }

    std::string msg = message->message;

    // Get the MessageArgs from the log if there are any
    std::span<std::string> messageArgs;
    if (logEntryFields.size() > 1)
    {
        std::string& messageArgsStart = logEntryFields[1];
        // If the first string is empty, assume there are no MessageArgs
        std::size_t messageArgsSize = 0;
        if (!messageArgsStart.empty())
        {
            messageArgsSize = logEntryFields.size() - 1;
        }

        messageArgs = {&messageArgsStart, messageArgsSize};

        // Fill the MessageArgs into the Message
        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 the Created time from the timestamp. The log timestamp is in RFC3339
    // format which matches the Redfish format except for the fractional seconds
    // between the '.' and the '+', so just remove them.
    std::size_t dot = timestamp.find_first_of('.');
    std::size_t plus = timestamp.find_first_of('+');
    if (dot != std::string::npos && plus != std::string::npos)
    {
        timestamp.erase(dot, plus - dot);
    }

    // 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", "system", "LogServices", "EventLog",
        "Entries", logEntryID);
    logEntryJson["Name"] = "System Event Log Entry";
    logEntryJson["Id"] = logEntryID;
    logEntryJson["Message"] = std::move(msg);
    logEntryJson["MessageId"] = std::move(messageID);
    logEntryJson["MessageArgs"] = messageArgs;
    logEntryJson["EntryType"] = "Event";
    logEntryJson["Severity"] = message->messageSeverity;
    logEntryJson["Created"] = std::move(timestamp);
    return LogParseError::success;
}

void requestRoutesJournalEventLogEntryCollection(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/")
        .privileges(redfish::privileges::getLogEntryCollection)
        .methods(boost::beast::http::verb::get)(
            [&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;
        }

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

        // 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/Systems/system/LogServices/EventLog/Entries";
        asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
        asyncResp->res.jsonValue["Description"] =
            "Collection of System Event Log Entries";

        nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
        logEntryArray = nlohmann::json::array();
        // Go through the log files and create a unique ID for each
        // entry
        std::vector<std::filesystem::path> redfishLogFiles;
        getRedfishLogFiles(redfishLogFiles);
        uint64_t entryCount = 0;
        std::string logEntry;

        // Oldest logs are in the last file, so start there and loop
        // backwards
        for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend();
             it++)
        {
            std::ifstream logStream(*it);
            if (!logStream.is_open())
            {
                continue;
            }

            // Reset the unique ID on the first entry
            bool firstEntry = true;
            while (std::getline(logStream, logEntry))
            {
                std::string idStr;
                if (!getUniqueEntryID(logEntry, idStr, firstEntry))
                {
                    continue;
                }
                firstEntry = false;

                nlohmann::json::object_t bmcLogEntry;
                LogParseError status =
                    fillEventLogEntryJson(idStr, logEntry, bmcLogEntry);
                if (status == LogParseError::messageIdNotInRegistry)
                {
                    continue;
                }
                if (status != LogParseError::success)
                {
                    messages::internalError(asyncResp->res);
                    return;
                }

                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;
                }

                logEntryArray.push_back(std::move(bmcLogEntry));
            }
        }
        asyncResp->res.jsonValue["Members@odata.count"] = entryCount;
        if (skip + top < entryCount)
        {
            asyncResp->res.jsonValue["Members@odata.nextLink"] =
                "/redfish/v1/Systems/system/LogServices/EventLog/Entries?$skip=" +
                std::to_string(skip + top);
        }
    });
}

void requestRoutesJournalEventLogEntry(App& app)
{
    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/<str>/LogServices/EventLog/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& param) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }

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

        const std::string& targetID = param;

        // Go through the log files and check the unique ID for each
        // entry to find the target entry
        std::vector<std::filesystem::path> redfishLogFiles;
        getRedfishLogFiles(redfishLogFiles);
        std::string logEntry;

        // Oldest logs are in the last file, so start there and loop
        // backwards
        for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend();
             it++)
        {
            std::ifstream logStream(*it);
            if (!logStream.is_open())
            {
                continue;
            }

            // Reset the unique ID on the first entry
            bool firstEntry = true;
            while (std::getline(logStream, logEntry))
            {
                std::string idStr;
                if (!getUniqueEntryID(logEntry, idStr, firstEntry))
                {
                    continue;
                }
                firstEntry = false;

                if (idStr == targetID)
                {
                    nlohmann::json::object_t bmcLogEntry;
                    LogParseError status =
                        fillEventLogEntryJson(idStr, logEntry, bmcLogEntry);
                    if (status != LogParseError::success)
                    {
                        messages::internalError(asyncResp->res);
                        return;
                    }
                    asyncResp->res.jsonValue.update(bmcLogEntry);
                    return;
                }
            }
        }
        // Requested ID was not found
        messages::resourceNotFound(asyncResp->res, "LogEntry", targetID);
    });
}

void requestRoutesDBusEventLogEntryCollection(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/")
        .privileges(redfish::privileges::getLogEntryCollection)
        .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;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }

        // 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/Systems/system/LogServices/EventLog/Entries";
        asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
        asyncResp->res.jsonValue["Description"] =
            "Collection of System Event Log Entries";

        managedStore::ManagedObjectStoreContext context(asyncResp);
        // DBus implementation of EventLog/Entries
        // Make call to Logging Service to find all log entry objects
        managedStore::managedObjectStore->getManagedObjectsWithContext(
            "xyz.openbmc_project.Logging", {"/xyz/openbmc_project/logging"},
            context,
            [asyncResp](const boost::system::error_code& ec,
                        const dbus::utility::ManagedObjectType& resp) {
            if (ec)
            {
                // TODO Handle for specific error code
                BMCWEB_LOG_ERROR
                    << "getLogEntriesIfaceData resp_handler got error " << ec;
                messages::internalError(asyncResp->res);
                return;
            }
            nlohmann::json& entriesArray = asyncResp->res.jsonValue["Members"];
            entriesArray = nlohmann::json::array();
            for (const auto& objectPath : resp)
            {
                const uint32_t* id = nullptr;
                const uint64_t* timestamp = nullptr;
                const uint64_t* updateTimestamp = nullptr;
                const std::string* severity = nullptr;
                const std::string* message = nullptr;
                const std::string* filePath = nullptr;
                const std::string* resolution = nullptr;
                bool resolved = false;
                const std::string* notify = nullptr;

                for (const auto& interfaceMap : objectPath.second)
                {
                    if (interfaceMap.first ==
                        "xyz.openbmc_project.Logging.Entry")
                    {
                        for (const auto& propertyMap : interfaceMap.second)
                        {
                            if (propertyMap.first == "Id")
                            {
                                id = std::get_if<uint32_t>(&propertyMap.second);
                            }
                            else if (propertyMap.first == "Timestamp")
                            {
                                timestamp =
                                    std::get_if<uint64_t>(&propertyMap.second);
                            }
                            else if (propertyMap.first == "UpdateTimestamp")
                            {
                                updateTimestamp =
                                    std::get_if<uint64_t>(&propertyMap.second);
                            }
                            else if (propertyMap.first == "Severity")
                            {
                                severity = std::get_if<std::string>(
                                    &propertyMap.second);
                            }
                            else if (propertyMap.first == "Resolution")
                            {
                                resolution = std::get_if<std::string>(
                                    &propertyMap.second);
                            }
                            else if (propertyMap.first == "Message")
                            {
                                message = std::get_if<std::string>(
                                    &propertyMap.second);
                            }
                            else if (propertyMap.first == "Resolved")
                            {
                                const bool* resolveptr =
                                    std::get_if<bool>(&propertyMap.second);
                                if (resolveptr == nullptr)
                                {
                                    messages::internalError(asyncResp->res);
                                    return;
                                }
                                resolved = *resolveptr;
                            }
                            else if (propertyMap.first ==
                                     "ServiceProviderNotify")
                            {
                                notify = std::get_if<std::string>(
                                    &propertyMap.second);
                                if (notify == nullptr)
                                {
                                    messages::internalError(asyncResp->res);
                                    return;
                                }
                            }
                        }
                        if (id == nullptr || message == nullptr ||
                            severity == nullptr)
                        {
                            messages::internalError(asyncResp->res);
                            return;
                        }
                    }
                    else if (interfaceMap.first ==
                             "xyz.openbmc_project.Common.FilePath")
                    {
                        for (const auto& propertyMap : interfaceMap.second)
                        {
                            if (propertyMap.first == "Path")
                            {
                                filePath = std::get_if<std::string>(
                                    &propertyMap.second);
                            }
                        }
                    }
                }
                // Object path without the
                // xyz.openbmc_project.Logging.Entry interface, ignore
                // and continue.
                if (id == nullptr || message == nullptr ||
                    severity == nullptr || timestamp == nullptr ||
                    updateTimestamp == nullptr)
                {
                    continue;
                }
                entriesArray.push_back({});
                nlohmann::json& thisEntry = entriesArray.back();
                thisEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
                thisEntry["@odata.id"] = crow::utility::urlFromPieces(
                    "redfish", "v1", "Systems", "system", "LogServices",
                    "EventLog", "Entries", std::to_string(*id));
                thisEntry["Name"] = "System Event Log Entry";
                thisEntry["Id"] = std::to_string(*id);
                thisEntry["Message"] = *message;
                thisEntry["Resolved"] = resolved;
                if ((resolution != nullptr) && (!(*resolution).empty()))
                {
                    thisEntry["Resolution"] = *resolution;
                }
                std::optional<bool> notifyAction =
                    getProviderNotifyAction(*notify);
                if (notifyAction)
                {
                    thisEntry["ServiceProviderNotified"] = *notifyAction;
                }
                thisEntry["EntryType"] = "Event";
                thisEntry["Severity"] =
                    translateSeverityDbusToRedfish(*severity);
                thisEntry["Created"] =
                    redfish::time_utils::getDateTimeUintMs(*timestamp);
                thisEntry["Modified"] =
                    redfish::time_utils::getDateTimeUintMs(*updateTimestamp);
                if (filePath != nullptr)
                {
                    thisEntry["AdditionalDataURI"] =
                        "/redfish/v1/Systems/system/LogServices/EventLog/Entries/" +
                        std::to_string(*id) + "/attachment";
                }
            }
            std::sort(
                entriesArray.begin(), entriesArray.end(),
                [](const nlohmann::json& left, const nlohmann::json& right) {
                return (left["Id"] <= right["Id"]);
            });
            asyncResp->res.jsonValue["Members@odata.count"] =
                entriesArray.size();
        });
    });
}

void requestRoutesDBusEventLogEntry(App& app)
{
    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/<str>/LogServices/EventLog/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& param) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }

        std::string entryID = param;
        dbus::utility::escapePathForDbus(entryID);

        // DBus implementation of EventLog/Entries
        // Make call to Logging Service to find all log entry objects
        managedStore::ManagedObjectStoreContext context(asyncResp);
        managedStore::managedObjectStore->getAllProperties(
            "xyz.openbmc_project.Logging",
            "/xyz/openbmc_project/logging/entry/" + entryID, "", context,
            [asyncResp, entryID](const boost::system::error_code& ec,
                                 const dbus::utility::DBusPropertiesMap& resp) {
            if (ec.value() == EBADR)
            {
                messages::resourceNotFound(asyncResp->res, "EventLogEntry",
                                           entryID);
                return;
            }
            if (ec)
            {
                BMCWEB_LOG_ERROR
                    << "EventLogEntry (DBus) resp_handler got error " << ec;
                messages::internalError(asyncResp->res);
                return;
            }
            const uint32_t* id = nullptr;
            const uint64_t* timestamp = nullptr;
            const uint64_t* updateTimestamp = nullptr;
            const std::string* severity = nullptr;
            const std::string* message = nullptr;
            const std::string* filePath = nullptr;
            const std::string* resolution = nullptr;
            bool resolved = false;
            const std::string* notify = nullptr;

            const bool success = sdbusplus::unpackPropertiesNoThrow(
                dbus_utils::UnpackErrorPrinter(), resp, "Id", id, "Timestamp",
                timestamp, "UpdateTimestamp", updateTimestamp, "Severity",
                severity, "Message", message, "Resolved", resolved,
                "Resolution", resolution, "Path", filePath,
                "ServiceProviderNotify", notify);

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

            if (id == nullptr || message == nullptr || severity == nullptr ||
                timestamp == nullptr || updateTimestamp == nullptr ||
                notify == nullptr)
            {
                messages::internalError(asyncResp->res);
                return;
            }

            asyncResp->res.jsonValue["@odata.type"] =
                "#LogEntry.v1_9_0.LogEntry";
            asyncResp->res.jsonValue["@odata.id"] =
                crow::utility::urlFromPieces(
                    "redfish", "v1", "Systems", "system", "LogServices",
                    "EventLog", "Entries", std::to_string(*id));
            asyncResp->res.jsonValue["Name"] = "System Event Log Entry";
            asyncResp->res.jsonValue["Id"] = std::to_string(*id);
            asyncResp->res.jsonValue["Message"] = *message;
            asyncResp->res.jsonValue["Resolved"] = resolved;
            std::optional<bool> notifyAction = getProviderNotifyAction(*notify);
            if (notifyAction)
            {
                asyncResp->res.jsonValue["ServiceProviderNotified"] =
                    *notifyAction;
            }
            if ((resolution != nullptr) && (!(*resolution).empty()))
            {
                asyncResp->res.jsonValue["Resolution"] = *resolution;
            }
            asyncResp->res.jsonValue["EntryType"] = "Event";
            asyncResp->res.jsonValue["Severity"] =
                translateSeverityDbusToRedfish(*severity);
            asyncResp->res.jsonValue["Created"] =
                redfish::time_utils::getDateTimeUintMs(*timestamp);
            asyncResp->res.jsonValue["Modified"] =
                redfish::time_utils::getDateTimeUintMs(*updateTimestamp);
            if (filePath != nullptr)
            {
                asyncResp->res.jsonValue["AdditionalDataURI"] =
                    "/redfish/v1/Systems/system/LogServices/EventLog/Entries/" +
                    std::to_string(*id) + "/attachment";
            }
        });
    });

    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
        .privileges(redfish::privileges::patchLogEntry)
        .methods(boost::beast::http::verb::patch)(
            [&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;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }
        std::optional<bool> resolved;

        if (!json_util::readJsonPatch(req, asyncResp->res, "Resolved",
                                      resolved))
        {
            return;
        }
        BMCWEB_LOG_DEBUG << "Set Resolved";

        crow::connections::systemBus->async_method_call(
            [asyncResp, entryId](const boost::system::error_code& ec) {
            if (ec)
            {
                BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
                messages::internalError(asyncResp->res);
                return;
            }
        },
            "xyz.openbmc_project.Logging",
            "/xyz/openbmc_project/logging/entry/" + entryId,
            "org.freedesktop.DBus.Properties", "Set",
            "xyz.openbmc_project.Logging.Entry", "Resolved",
            dbus::utility::DbusVariantType(*resolved));
    });

    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/<str>/LogServices/EventLog/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& param) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }
        BMCWEB_LOG_DEBUG << "Do delete single event entries.";

        std::string entryID = param;

        dbus::utility::escapePathForDbus(entryID);

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

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

        // Make call to Logging service to request Delete Log
        crow::connections::systemBus->async_method_call(
            respHandler, "xyz.openbmc_project.Logging",
            "/xyz/openbmc_project/logging/entry/" + entryID,
            "xyz.openbmc_project.Object.Delete", "Delete");
    });
}

void requestRoutesDBusEventLogEntryDownload(App& app)
{
    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/attachment")
        .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& param) {
        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;
        }

        std::string entryID = param;
        dbus::utility::escapePathForDbus(entryID);

        crow::connections::systemBus->async_method_call(
            [asyncResp, entryID](const boost::system::error_code& ec,
                                 const sdbusplus::message::unix_fd& unixfd) {
            if (ec.value() == EBADR)
            {
                messages::resourceNotFound(asyncResp->res, "EventLogAttachment",
                                           entryID);
                return;
            }
            if (ec)
            {
                BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
                messages::internalError(asyncResp->res);
                return;
            }

            int fd = -1;
            fd = dup(unixfd);
            if (fd == -1)
            {
                messages::internalError(asyncResp->res);
                return;
            }

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

            // Arbitrary max size of 64kb
            constexpr int maxFileSize = 65536;
            if (size > maxFileSize)
            {
                BMCWEB_LOG_ERROR << "File size exceeds maximum allowed size of "
                                 << maxFileSize;
                messages::internalError(asyncResp->res);
                return;
            }
            std::vector<char> data(static_cast<size_t>(size));
            long long int 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 = crow::utility::base64encode(strData);

            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() = std::move(output);
        },
            "xyz.openbmc_project.Logging",
            "/xyz/openbmc_project/logging/entry/" + entryID,
            "xyz.openbmc_project.Logging.Entry", "GetEntry");
    });
}

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

void requestRoutesSystemHostLoggerCollection(App& app)
{
    BMCWEB_ROUTE(app,
                 "/redfish/v1/Systems/<str>/LogServices/HostLogger/Entries/")
        .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) {
        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);
        });
    });
}

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

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)(
            [&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);
        });
    });
}

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::managedObjectStore->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)));
}

void requestRoutesBMCJournalLogService(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Journal/")
        .privileges(redfish::privileges::getLogService)
        .methods(boost::beast::http::verb::get)(
            [&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";
    });
}

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
    long int 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;
}

void requestRoutesBMCJournalLogEntryCollection(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Journal/Entries/")
        .privileges(redfish::privileges::getLogEntryCollection)
        .methods(boost::beast::http::verb::get)(
            [&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 requestRoutesBMCJournalLogEntry(App& app)
{
    BMCWEB_ROUTE(app,
                 "/redfish/v1/Managers/bmc/LogServices/Journal/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& 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);
    });
}

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::managedObjectStore->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)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    getDumpEntryCollection(asyncResp, Dump{.type=dumpType});
}

inline void handleLogServicesDumpEntriesCollectionComputerSystemGet(
    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;
    }
    getDumpEntryCollection(asyncResp, Dump{.type=DumpType::SYSTEM_DUMP});
}

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

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)(
            [&app](const crow::Request& req,
                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                   const std::string& systemName) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }
        getDumpEntryCollection(asyncResp,
            Dump{.type=DumpType::SYSTEM_FAULT_LOG, .systemName=systemName});
    });
}

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

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)(
            [&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 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)(
            [&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;
        }
        crow::connections::systemBus->async_method_call(
            [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");
    });
}

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::managedObjectStore->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 populateJsonDumpEntry(nlohmann::json& thisEntry,
                                      const std::string& entryID,
                                      const uint64_t& timestampUs,
                                      const FaultlogType& faultlogType)
{
    std::string dumpType;
    if(faultlogType == FaultlogType::Crashdump)
    {
        thisEntry["Name"] = "CPU Crashdump Entry";
        thisEntry["DiagnosticDataType"] = "OEM";
        thisEntry["OEMDiagnosticDataType"] = "BERT";
        dumpType = crashDumpLogServiceName;
    }
    else if (faultlogType == FaultlogType::HostCper)
    {
        thisEntry["Name"] = "Host CPER Entry";
        thisEntry["DiagnosticDataType"] = "CPER";
        dumpType = hostCperLogServiceName;
    }
    else
    {
        BMCWEB_LOG_DEBUG << "Unexpected faultlog type";
        return;
    }
    thisEntry["@odata.type"] = "#LogEntry.v1_11_0.LogEntry";
    thisEntry["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Systems", "system", "LogServices",
        dumpType, "Entries", entryID);
    thisEntry["Id"] = entryID;
    thisEntry["EntryType"] = "Oem";
    thisEntry["Created"] = redfish::time_utils::getDateTimeUintUs(timestampUs);
    thisEntry["AdditionalDataURI"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Systems", "system", "LogServices",
        dumpType, "Entries", entryID, "attachment");
}

inline bool parseFaultLogTypeFromDbusObject(
    const dbus::utility::ManagedObjectType::value_type& object,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& log_type)
{
    for (const auto& interfaceMap : object.second)
    {
        if (interfaceMap.first == "xyz.openbmc_project.Dump.Entry.FaultLog")
        {
            for (const auto& propertyMap : interfaceMap.second)
            {
                if (propertyMap.first == "Type")
                {
                    const std::string* LogType =
                        std::get_if<std::string>(&propertyMap.second);
                    if (LogType == nullptr)
                    {
                        messages::internalError(asyncResp->res);
                        break;
                    }
                    if (*LogType ==
                         ("xyz.openbmc_project.Dump.Entry.FaultLog.FaultDataType." + log_type))
                    {
                        return true;
                    }
                }
            }
            break;
        }
    }
    return false;
}

inline void
    setFaultLogManagerPaths(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                            const FaultlogType& faultlogType, std::string& logType,
                            std::string& logService, std::string& logObjManagerPath)
{
    if(faultlogType == FaultlogType::Crashdump)
    {
        logType = "Crashdump";
        logService = crashDumpService;
        logObjManagerPath = crashDumpObjManagerPath;
    }
    else if(faultlogType == FaultlogType::HostCper)
    {
        logType = "CPER";
        logService = hostCperService;
        logObjManagerPath = hostCperObjManagerPath;
    }
    else
    {
        BMCWEB_LOG_DEBUG << "Unexpected faultlog type";
        messages::internalError(asyncResp->res);
        return;
    }
}

inline void
    getFaultLogEntryById(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                         const std::string& entryID, const FaultlogType& faultlogType)
{
    std::string logType, logService, logObjManagerPath;
    setFaultLogManagerPaths(asyncResp, faultlogType, logType, logService, logObjManagerPath);

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
        dbus_utils::getProperty<uint64_t>(
            logService,
            std::string(logObjManagerPath) + "/faultlog/entry/" + entryID,
            "xyz.openbmc_project.Time.EpochTime", "Elapsed",
            requestContext,
            [asyncResp, entryID, faultlogType, logType, logService, logObjManagerPath]
                (const boost::system::error_code ec,
                 const uint64_t timestampUs) {
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "Faultlog entry get property response error "
                             << ec;
            messages::internalError(asyncResp->res);
            return;
        }

        managedStore::ManagedObjectStoreContext requestContext(asyncResp);
            dbus_utils::getProperty<std::string>(
                logService,
                std::string(logObjManagerPath) + "/faultlog/entry/" + entryID,
                "xyz.openbmc_project.Dump.Entry.FaultLog", "Type",
                requestContext,
                [asyncResp, entryID, faultlogType, logType, timestampUs]
                    (const boost::system::error_code ec1,
                     const std::string type) {
            if (ec1)
            {
                BMCWEB_LOG_DEBUG << "Faultlog entry get property response error "
                                 << ec1;
                messages::internalError(asyncResp->res);
                return;
            }
            if (type != ("xyz.openbmc_project.Dump.Entry.FaultLog.FaultDataType." + logType))
            {
                BMCWEB_LOG_DEBUG << "Faultlog entry wrong type, expected: "
                                 << logType << ", actual: " << type;
                messages::internalError(asyncResp->res);
                return;
            }
            populateJsonDumpEntry(asyncResp->res.jsonValue, entryID,
                                            timestampUs, faultlogType);
        });
    });
}

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)(
            [&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;
        }

#ifdef BMCWEB_ENABLE_REDFISH_CRASHDUMP_BERT
            // Get all object paths and their interfaces for current connection

        managedStore::ManagedObjectStoreContext context(asyncResp);
        managedStore::managedObjectStore->getManagedObjectsWithContext(
            crashDumpService, std::string(crashDumpObjManagerPath), context,
            [asyncResp](
                const boost::system::error_code& ec,
                const dbus::utility::ManagedObjectType& managedObjects) {
            if (ec)
            {
                BMCWEB_LOG_ERROR
                    << "Crashdump Entry Collection resp_handler got error "
                    << ec;
                messages::internalError(asyncResp->res);
                return;
            }

            dbus::utility::ManagedObjectType& resp =
                const_cast<dbus::utility::ManagedObjectType&>(managedObjects);
            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";

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

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

            for (auto& object : resp)
            {
                if (object.first.str.find(std::string(crashDumpObjManagerPath) +
                                          "/") == std::string::npos)
                {
                    continue;
                }

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

                if (!parseFaultLogTypeFromDbusObject(object, asyncResp, "Crashdump"))
                {
                    continue;
                }

                uint64_t timestampUs = 0;
                parseElapsedTimestampFromDbusObject(object, timestampUs,
                                                    asyncResp);

                nlohmann::json thisEntry;
                populateJsonDumpEntry(thisEntry, entryID, timestampUs, FaultlogType::Crashdump);

                entriesArray.push_back(std::move(thisEntry));
            }
            asyncResp->res.jsonValue["Members@odata.count"] =
                entriesArray.size();
            });
#else
        constexpr std::array<std::string_view, 1> interfaces = {
            crashdumpInterface};
        managedStore::ManagedObjectStoreContext requestContext(asyncResp);
        managedStore::managedObjectStore->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"]);
            }
        });
#endif
    });
}

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)(
            [&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;

#ifdef BMCWEB_ENABLE_REDFISH_CRASHDUMP_BERT
        getFaultLogEntryById(asyncResp, logID, FaultlogType::Crashdump);
#else
        logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue);
#endif
    });
}

void requestRoutesCrashdumpFile(App& app)
{
    // Note: Deviated from redfish privilege registry for GET & HEAD
    // method for security reasons.
#ifdef BMCWEB_ENABLE_REDFISH_CRASHDUMP_BERT
    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/<str>/attachment")
        .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& entryID) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }

        managedStore::ManagedObjectStoreContext requestContext(asyncResp);
            dbus_utils::getProperty<std::string>(
                crashDumpService,
                std::string(crashDumpObjManagerPath) + "/faultlog/entry/" + entryID,
                "xyz.openbmc_project.Dump.Entry.FaultLog", "PrimaryLogId",
                requestContext,
                [asyncResp](const boost::system::error_code ec,
                                    const std::string primaryLogId) {
                if (ec)
                {
                    BMCWEB_LOG_DEBUG << "Crashdump entry get property response error "
                                    << ec;
                    messages::internalError(asyncResp->res);
                    return;
                }

                std::string faultLogDir = crashDumpLogPath;
                std::string path = faultLogDir + primaryLogId;
                FILE* fp = fopen(path.c_str(), "rb");
                if (fp == NULL)
                {
                    BMCWEB_LOG_ERROR << "The FaultLog Dir does not exist: " << path.c_str();
                    messages::internalError(asyncResp->res);
                    return;
                }
                auto fd = fileno(fp);
                long long int size = lseek(fd, 0, SEEK_END);
                if (size == -1)
                {
                    messages::internalError(asyncResp->res);
                    return;
                }

                std::vector<char> data(static_cast<size_t>(size));
                long long int 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 output(data.data(), data.size());
                asyncResp->res.body() = std::move(output);
        });
    });
#else
    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/<str>/")
        .privileges(redfish::privileges::getLogEntry)
        .methods(boost::beast::http::verb::get)(
            [](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::managedObjectStore->getAllProperties(
            crashdumpObject, crashdumpPath + std::string("/") + logID,
            crashdumpInterface, context, std::move(getStoredLogCallback));
    });
#endif
}

enum class OEMDiagnosticType
{
    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;
}

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)(
            [&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));
        };

        crow::connections::systemBus->async_method_call(
            std::move(collectCrashdumpCallback), crashdumpObject, crashdumpPath,
            iface, method);
    });
}

/**
 * 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)(
            [&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
        crow::connections::systemBus->async_method_call(
            respHandler, "xyz.openbmc_project.Logging",
            "/xyz/openbmc_project/logging",
            "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
    });
}

/****************************************************
 * 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)(
            [&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"}};
    });
}

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)(
            [&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
        crow::connections::systemBus->async_method_call(
            [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");
    });
}

/**
 * @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;
    }

    crow::connections::systemBus->async_method_call(
        [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)
{
    crow::connections::systemBus->async_method_call(
        [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);
    });
}

void requestRoutesPostCodesEntryCollection(App& app)
{
    BMCWEB_ROUTE(app,
                 "/redfish/v1/Systems/<str>/LogServices/PostCodes/Entries/")
        .privileges(redfish::privileges::getLogEntryCollection)
        .methods(boost::beast::http::verb::get)(
            [&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 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)(
            [&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;
        }

        crow::connections::systemBus->async_method_call(
            [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 requestRoutesPostCodesEntry(App& app)
{
    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/<str>/LogServices/PostCodes/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& targetID) {
        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
        {
            return;
        }
        if (systemName != "system")
        {
            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                       systemName);
            return;
        }

        getPostCodeForEntry(asyncResp, targetID);
    });
}

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)
{
    crow::connections::systemBus->async_method_call(
        [aResp, parentODataId, specificIndex,
         successCb{std::move(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 (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)
{
    crow::connections::systemBus->async_method_call(
        [aResp, parentODataId, specificIndex,
         successCb{std::move(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 (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{std::move(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()))
        {
            auto [_, ec] =
                std::from_chars(entryId.c_str() + type.length(),
                                entryId.c_str() + entryId.length(), index);
            // calling std::errc without any argument means successful parse
            if (ec != std::errc())
            {
                return false;
            }
            dataType = static_cast<BootTimeDataType>(typeIndex);
            if (dataType == BootTimeDataType::STATISTIC && index != 0)
            {
                return false;
            }
            return true;
        }
        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.size() == 0)
    {
        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;
    size_t index;
    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)));
}

} // namespace redfish
