#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 "log_services.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"

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

namespace redfish
{

inline void handleGetEventLogService(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    if (systemName != "system")
    {
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   systemName);
        return;
    }
    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/Systems/system/LogServices/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 requestRoutesEventLogService(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/")
        .privileges(redfish::privileges::getLogService)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleGetEventLogService, std::ref(app)));
}

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 void handlePostJournalEventLogClear(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    if (systemName != "system")
    {
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   systemName);
        return;
    }
    // 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
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [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");
}

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

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

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 void handleGetJournalEventLogEntryCollection(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName)
{
    query_param::QueryCapabilities capabilities = {
        .canDelegateTop = true,
        .canDelegateSkip = true,
    };
    query_param::Query delegatedQuery;
    if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
                                                  delegatedQuery, capabilities))
    {
        return;
    }
    if (systemName != "system")
    {
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   systemName);
        return;
    }

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

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

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

    const std::string& 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 requestRoutesJournalEventLogEntry(App& app)
{
    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
        .privileges(redfish::privileges::getLogEntry)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleGetJournalEventLogEntry, std::ref(app)));
}

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

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

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

void handleDeleteEventLogEntry(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& param)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    if (systemName != "system")
    {
        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
                                   systemName);
        return;
    }
    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
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        respHandler, "xyz.openbmc_project.Logging",
        "/xyz/openbmc_project/logging/entry/" + entryID,
        "xyz.openbmc_project.Object.Delete", "Delete");
}

void handlePatchEventLogEntry(
    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;
    }
    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";

    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [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));
}

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

    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::GetManagedObjectStore()->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";
        }
    });
}

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)(
            std::bind_front(handleGetDBusEventLogEntry, std::ref(app)));

    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
        .privileges(redfish::privileges::patchLogEntry)
        .methods(boost::beast::http::verb::patch)(
            std::bind_front(handlePatchEventLogEntry, std::ref(app)));

    BMCWEB_ROUTE(
        app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
        .privileges(redfish::privileges::deleteLogEntry)

        .methods(boost::beast::http::verb::delete_)(
            std::bind_front(handleDeleteEventLogEntry, std::ref(app)));
}

inline void handleGetDBusEventLogEntryDownload(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::string& param)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    if (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);

    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [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;
        }

        int64_t 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));
        int64_t rc = lseek(fd, 0, SEEK_SET);
        if (rc == -1)
        {
            messages::internalError(asyncResp->res);
            return;
        }
        rc = read(fd, data.data(), data.size());
        if ((rc == -1) || (rc != size))
        {
            messages::internalError(asyncResp->res);
            return;
        }
        close(fd);

        std::string_view strData(data.data(), data.size());
        std::string output = 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");
}

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)(
            std::bind_front(handleGetDBusEventLogEntryDownload, std::ref(app)));
}

} // namespace redfish
