#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <ctime>
#include <filesystem>  // NOLINT
#include <fstream>
#include <functional>
#include <iomanip>
#include <memory>
#include <optional>
#include <span>  // NOLINT
#include <sstream>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT
#include <utility>
#include <variant>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/strings/str_cat.h"
#include "app.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "http_utility.hpp"
#include "str_utility.hpp"
#include "error_messages.hpp"
#include "query.hpp"
#include "registries.hpp"
#include "registries/privilege_registry.hpp"
#include "dbus_utils.hpp"
#include "json_utils.hpp"
#include "time_utils.hpp"
#include "log_services.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message/native_types.hpp"
#include "sdbusplus/unpack_properties.hpp"

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_,
      absl::AnyInvocable<void(const boost::system::error_code&)>(
          [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
  const std::string serviceName = "xyz.openbmc_project.Logging";
  const std::string objectPath =
      absl::StrCat("/xyz/openbmc_project/logging/entry/", entryID);
  const std::string interfaceName = "xyz.openbmc_project.Object.Delete";
  const std::string method = "Delete";

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      absl::AnyInvocable<void(const boost::system::error_code&)>(
          std::move(respHandler)),
      serviceName, objectPath, interfaceName, method);
}

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

  const std::string serviceName = "xyz.openbmc_project.Logging";
  const std::string objectPath =
      absl::StrCat("/xyz/openbmc_project/logging/entry/", entryId);
  const std::string interfaceName = "org.freedesktop.DBus.Properties";
  const std::string setMethod = "Set";
  const std::string setInterface = "xyz.openbmc_project.Logging.Entry";
  const std::string propertyName = "Resolved";

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      absl::AnyInvocable<void(const boost::system::error_code&)>(
          [asyncResp, entryId](const boost::system::error_code& ec) {
            if (ec) {
              BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
              messages::internalError(asyncResp->res);
              return;
            }
          }),
      serviceName, objectPath, interfaceName, setMethod, setInterface,
      propertyName, 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_,
      absl::AnyInvocable<void(const boost::system::error_code&,
                              const sdbusplus::message::unix_fd&)>(
          [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",
      absl::StrCat("/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
