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

#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
