#include "sse_plugin/event.h"

#include <cstdint>
#include <string>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/container/flat_hash_map.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
#include "proxy_config.pb.h"
#include "events.pb.h"
#include "vendor_events.pb.h"
#include "utils/status_macros.h"

namespace milotic {

namespace {
const int kVlogVerbosity = 1;

using ::platforms_vbmc::OtsEvent;
using ::platforms_vbmc::OtsUpdate;

// Finds MessageId from parsed_event, if exists, and parses it based Redfish
// format.
// <MessageRegistryPrefix>.<MajorVersion>.<MinorVersion>.<MessageKey>
absl::StatusOr<EventMessageId> FindEventMessageId(
    const nlohmann::json& parsed_event) {
  if (!parsed_event.is_object()) {
    return absl::NotFoundError("event json is not object");
  }
  const auto message_id_it = parsed_event.find("MessageId");
  if (message_id_it == parsed_event.end()) {
    VLOG(kVlogVerbosity) << "event json does not contain MessageId"
                         << parsed_event.dump();
    return absl::NotFoundError("event json does not contain MessageId");
  }
  const auto* message_id = message_id_it.value().get_ptr<const std::string*>();
  if (message_id == nullptr) {
    return absl::InvalidArgumentError("MessageId is not string");
  }

  std::vector<std::string> message_id_parts = absl::StrSplit(*message_id, '.');
  if (message_id_parts.size() != 4) {
    return absl::InvalidArgumentError("MessageId not in correct format");
  }

  return EventMessageId{
      .message_registry_prefix = std::move(message_id_parts[0]),
      .major_version = std::move(message_id_parts[1]),
      .minor_version = std::move(message_id_parts[2]),
      .message_key = std::move(message_id_parts[3]),
  };
}

// Finds ReasonId from OemPath whose value should be an array each of which
// contains `Reasons` which is an array each of which contains a `ReasonId` and
// `DateTime`, we select the `ReasonId` which has the max `DateTime`.
// Eg {"OemField": [{"Reasons": [{"ReasonId": xxx, "DateTime": yyy}]}]}
absl::StatusOr<int> FindReasonIdFromOemPath(
    const nlohmann::json& parsed_event,
    const nlohmann::json::json_pointer& oem_path) {
  absl::TimeZone tz = absl::LocalTimeZone();
  if (!parsed_event.is_object()) {
    return absl::NotFoundError("event json is not object");
  }

  if (!parsed_event.contains(oem_path)) {
    return absl::NotFoundError("event json does not Oem field");
  }

  const nlohmann::json& faults = parsed_event[oem_path];
  if (!faults.is_array())
    return absl::NotFoundError("faults in event json is null/not array");

  int reason_id = -1;
  for (auto fault : faults) {
    if (!fault.is_object()) continue;
    auto it = fault.find("Reasons");
    if (it == fault.end()) continue;
    const nlohmann::json& reasons = it.value();
    if (!reasons.is_array()) continue;

    absl::Time max_time;
    for (auto reason : reasons) {
      absl::Time reason_time;
      std::string error_string;
      std::string* time_value = reason["DateTime"].get_ptr<std::string*>();
      std::int64_t* reason_value = reason["ReasonId"].get_ptr<std::int64_t*>();
      if (time_value == nullptr || reason_value == nullptr) {
        return absl::InvalidArgumentError(absl::StrFormat(
            "Failed to parse time/reasonID from reason: %s", reason.dump()));
      }
      absl::ParseTime("%Y-%m-%dT%H:%M:%SZ", *time_value, tz, &reason_time,
                      &error_string);
      if (!error_string.empty()) {
        return absl::InvalidArgumentError(absl::StrFormat(
            "Failed to parse time from value: %s", *time_value));
      }
      if (reason_time > max_time) {
        max_time = reason_time;
        reason_id = static_cast<int>(*reason_value);
      }
    }
  }

  if (reason_id == -1)
    return absl::NotFoundError("No reason ID found in event");

  return reason_id;
}

// Finds ReasonId from MessageArgs which is any array of strings and
// ReasonIdMessageArgsIndex which has 2 values MessageKey and MessageArgIndex,
// if MessageKey matches the event message key, then reason id is the
// present in MessageArgs at the MessageArgIndex position.
// Eg ReasonIdMessageArgsIndex: {ResourceIndicted, 1}
// {"MessageId":"H3Alert.1.1.ResourceIndicted", "MessageArgs":["0",
// "1349"]}
// In this case 1349 is at index 1 which should be converted to int.
absl::StatusOr<int> FindReasonIdFromMessageArg(
    const nlohmann::json& parsed_event, absl::string_view message_key,
    const milotic_grpc_proxy::EventReasonIdParse::ReasonIdMessageArgsIndex&
        message_args_config) {
  if (message_key != message_args_config.message_key()) {
    return absl::NotFoundError("MessageKey mismatch");
  }

  auto it = parsed_event.find("MessageArgs");
  if (it == parsed_event.end()) {
    return absl::NotFoundError("MessageArgs not found");
  }

  const nlohmann::json& message_args = it.value();
  if (!message_args.is_array())
    return absl::NotFoundError("message_args in event json is null/not array");
  if (message_args_config.message_arg_index() >=
      static_cast<int>(message_args.size()))
    return absl::NotFoundError("MessageArgIndex out of bounds");

  const auto* reason_id_from_message_arg =
      message_args.at(message_args_config.message_arg_index())
          .get_ptr<const std::string*>();

  // ReasonID is present in string which has to be converted to int.
  int reason_id = -1;
  if (reason_id_from_message_arg != nullptr &&
      absl::SimpleAtoi(*reason_id_from_message_arg, &reason_id)) {
    VLOG(kVlogVerbosity) << "reason id " << reason_id
                         << " found in MessageArgs";
    return reason_id;
  }
  return absl::NotFoundError("No reason ID found in MessageArgs");
}

absl::StatusOr<EventSeverity> FindReasonSeverity(
    const absl::flat_hash_map<int, platforms_vbmc::VendorEvent>& registry,
    int reason_id) {
  auto it = registry.find(reason_id);
  if (it != registry.end()) {
    switch (it->second.severity()) {
      case platforms_vbmc::OtsEvent::SEVERITY_OK:
        return EventSeverity::kOk;
      case platforms_vbmc::OtsEvent::SEVERITY_LOG:
        return EventSeverity::kLog;
      case platforms_vbmc::OtsEvent::SEVERITY_WARNING:
        return EventSeverity::kWarning;
      case platforms_vbmc::OtsEvent::SEVERITY_CRITICAL:
        return EventSeverity::kCritical;
      default:
        return absl::InvalidArgumentError("Invalid event severity");
    }
  }

  return absl::NotFoundError(
      absl::StrFormat("Reason ID %d not found in registry", reason_id));
}

absl::string_view GetValueOrDefault(const nlohmann::json& json,
                                    absl::string_view key) {
  if (!json.is_object()) return "";

  auto it = json.find(key);
  if (it == json.end()) return "";

  const auto* value = it.value().get_ptr<const std::string*>();
  if (value == nullptr) return "";
  return *value;
}

absl::StatusOr<Event> CreateEvent(const EventParseConfig& parse_config,
                                  nlohmann::json parsed_event) {
  // Validate and parse event ID.
  int64_t event_id;
  int reason_id = kInvalidReasonId;
  auto event_id_it = parsed_event.find("EventId");
  if (event_id_it == parsed_event.end()) {
    return absl::InvalidArgumentError("EventId not found");
  }
  if (!absl::SimpleAtoi(absl::StrReplaceAll(event_id_it->dump(), {{"\"", ""}}),
                        &event_id)) {
    return absl::InvalidArgumentError("EventId is not a number");
  }
  VLOG(kVlogVerbosity) << "event id " << event_id;

  if (GetValueOrDefault(parsed_event, "MessageSeverity") == "OK") {
    // No parsing required for OK events
    return Event(parsed_event.dump(), event_id, EventSeverity::kOk);
  }

  absl::string_view message_severity =
      GetValueOrDefault(parsed_event, "MessageSeverity");

  // Log Non OK events
  // EventId, MessageSeverity, MessageId, Message, EventTimestamp
  LOG(INFO) << "Creating event with EventId: " << event_id
            << ", MessageSeverity: " << message_severity
            << ", MessageId: " << GetValueOrDefault(parsed_event, "MessageId")
            << ", Message: " << GetValueOrDefault(parsed_event, "Message")
            << ", Timestamp: "
            << GetValueOrDefault(parsed_event, "EventTimestamp");

  absl::StatusOr<EventMessageId> message_id = FindEventMessageId(parsed_event);

  // TODO: b/323233763 - Break into smaller functions
  // Check if MessageKey is ignored.
  if (parse_config.event_parse.ignore_event_sev_message_keys_size() > 0) {
    if (!message_id.ok()) return message_id.status();

    VLOG(kVlogVerbosity) << "Searching MessageKey in ignore list: "
                         << message_id->message_key;
    if (absl::c_linear_search(
            parse_config.event_parse.ignore_event_sev_message_keys(),
            message_id->message_key)) {
      LOG(INFO) << "EventId: " << event_id
                << " created with OK Severity, message key "
                << message_id->message_key << " in ignore list";
      return Event(parsed_event.dump(), event_id, EventSeverity::kOk);
    }
  }

  // Check if MessageRegistryPrefix is ignored.
  if (parse_config.event_parse.ignore_event_sev_message_prefix_size() > 0) {
    if (!message_id.ok()) return message_id.status();

    VLOG(kVlogVerbosity) << "Searching MessageRegistryPrefix in ignore list: "
                         << message_id->message_registry_prefix;
    if (absl::c_linear_search(
            parse_config.event_parse.ignore_event_sev_message_prefix(),
            message_id->message_registry_prefix)) {
      LOG(INFO) << "EventId: " << event_id
                << " created with OK Severity, message prefix "
                << message_id->message_registry_prefix << " in ignore list";
      return Event(parsed_event.dump(), event_id, EventSeverity::kOk);
    }
  }

  // Check if ReasonId parsing is present.
  if (parse_config.event_parse.reason_id_parse_size() > 0) {
    for (const auto& reason_id_parse :
         parse_config.event_parse.reason_id_parse()) {
      // Check ReasonId in Oem Field.
      if (reason_id_parse.has_oem_field_path()) {
        VLOG(kVlogVerbosity) << "Checking ReasonId in Oem field";
        nlohmann::json::json_pointer oem_path(reason_id_parse.oem_field_path());
        if (absl::StatusOr<int> from_oem_path =
                FindReasonIdFromOemPath(parsed_event, oem_path);
            from_oem_path.ok()) {
          reason_id = *from_oem_path;
          VLOG(kVlogVerbosity)
              << "reason id " << reason_id << " found in Oem field";
          break;
        }
      }

      // Check ReasonId in MessageArgs.
      if (reason_id_parse.has_message_args_index()) {
        if (!message_id.ok()) return message_id.status();

        if (absl::StatusOr<int> reason_id_from_message_arg =
                FindReasonIdFromMessageArg(
                    parsed_event, message_id->message_key,
                    reason_id_parse.message_args_index());
            reason_id_from_message_arg.ok()) {
          reason_id = *reason_id_from_message_arg;
          VLOG(kVlogVerbosity)
              << "reason id " << reason_id << " found in MessageArgs";
          break;
        }
      }

      // Check ReasonId in Message string using regex.
      if (reason_id_parse.has_message_string_regex()) {
        // TODO: b/323233763 - Add support for Message string regex.
      }
    }
  }

  // If ReasonId is found, get severity from registry
  if (!parse_config.registry.empty() && reason_id != kInvalidReasonId) {
    if (absl::StatusOr<EventSeverity> severity =
            FindReasonSeverity(parse_config.registry, reason_id);
        severity.ok()) {
      LOG(INFO) << "EventId: " << event_id << " created with "
                << EventSeverityToString(*severity)
                << " Severity, reasonId: " << reason_id;
      return Event(parsed_event.dump(), event_id, *severity, reason_id);
    }
  }

  // If ignore_event_sev_wo_reason_id is set and we can't find ReasonId
  if (reason_id == kInvalidReasonId &&
      parse_config.event_parse.ignore_event_sev_wo_reason_id()) {
    LOG(INFO) << "EventId: " << event_id
              << " created with OK Severity, missing reasonId";
    return Event(parsed_event.dump(), event_id, EventSeverity::kOk);
  }

  // Finally use MessageSeverity for event severity.
  ASSIGN_OR_RETURN(EventSeverity severity,
                   StringToEventSeverity(message_severity));
  LOG(INFO) << "EventId: " << event_id << " created with "
            << EventSeverityToString(severity)
            << " Severity, using MessageSeverity";
  return Event(parsed_event.dump(), event_id, severity, reason_id);
}

}  // namespace

std::string EventSeverityToString(EventSeverity severity) {
  switch (severity) {
    case EventSeverity::kOk:
      return "OK";
    case EventSeverity::kLog:
      return "Log";
    case EventSeverity::kWarning:
      return "Warning";
    case EventSeverity::kCritical:
      return "Critical";
    default:
      return "";
  }
}

absl::StatusOr<EventSeverity> StringToEventSeverity(
    absl::string_view severity) {
  if (severity == "OK") {
    return EventSeverity::kOk;
  }
  if (severity == "Warning") {
    return EventSeverity::kWarning;
  }
  if (severity == "Critical") {
    return EventSeverity::kCritical;
  }
  return absl::InvalidArgumentError("Invalid message severity");
}

OtsUpdate Event::ToProto() const {
  OtsUpdate ots_update;
  OtsEvent event_proto;

  switch (severity_) {
    case EventSeverity::kOk:
      event_proto.set_severity(OtsEvent::SEVERITY_OK);
      break;
    case EventSeverity::kLog:
      event_proto.set_severity(OtsEvent::SEVERITY_LOG);
      break;
    case EventSeverity::kWarning:
      event_proto.set_severity(OtsEvent::SEVERITY_WARNING);
      break;
    case EventSeverity::kCritical:
      event_proto.set_severity(OtsEvent::SEVERITY_CRITICAL);
      break;
  }
  event_proto.mutable_event_json()->assign(event_json_);
  *ots_update.mutable_event() = event_proto;
  return ots_update;
}

absl::StatusOr<std::vector<Event>> Event::ParseRedfishEvent(
    const EventParseConfig& parse_config, absl::string_view event_json) {
  nlohmann::json parsed = nlohmann::json::parse(event_json, /*cb=*/nullptr,
                                                /*allow_exceptions=*/false);
  if (parsed.is_discarded()) {
    return absl::InvalidArgumentError("Failed to parse json");
  }
  // parsed json should be similar to
  // {"Id": 123, "Events": [{"EventId": 123, ...}]}.
  if (!parsed.is_object()) {
    return absl::InvalidArgumentError(
        "Invalid event json, json is not an object");
  }

  // Validated `Id` is present.
  auto id_it = parsed.find("Id");
  if (id_it == parsed.end()) {
    return absl::InvalidArgumentError("Invalid event json, Id is not present");
  }
  std::string* id_ptr = id_it->get_ptr<std::string*>();
  if (id_ptr == nullptr) {
    return absl::InvalidArgumentError("Id is not a string");
  }

  // Validate `Events` is present.
  auto events_it = parsed.find("Events");
  if (events_it == parsed.end()) {
    return absl::InvalidArgumentError(
        "Invalid event json, Events is not present");
  }

  // Validate `Events` json is an array and contains at least one event.
  if (!events_it->is_array() || events_it->size() != 1) {
    return absl::InvalidArgumentError(
        "Invalid event json, Events should be an array with single element");
  }

  if (!events_it->at(0).is_object()) {
    return absl::InvalidArgumentError(
        absl::StrFormat("Invalid event json, Events[0] is not an object"));
  }

  if (!events_it->at(0).contains("EventId")) {
    return absl::InvalidArgumentError(absl::StrFormat(
        "Invalid event json, EventId is not present in Events[0]"));
  }

  std::string* event_id_ptr =
      events_it->at(0)["EventId"].get_ptr<std::string*>();
  if (event_id_ptr == nullptr) {
    return absl::InvalidArgumentError("EventId is not a string");
  }

  if (*id_ptr != *event_id_ptr) {
    return absl::InvalidArgumentError(
        absl::StrFormat("EventId mismatch, Id: %s, Events[0][EventId]: %s",
                        *id_ptr, *event_id_ptr));
  }

  absl::StatusOr<Event> event = CreateEvent(parse_config, events_it->at(0));
  if (!event.ok()) {
    return event.status();
  }
  return std::vector<Event>{std::move(*event)};
}

absl::StatusOr<std::vector<Event>> Event::ParseReplayEvents(
    const EventParseConfig& parse_config, absl::string_view event_json) {
  std::vector<Event> events;
  if (event_json.empty()) {
    return events;
  }
  nlohmann::json parsed = nlohmann::json::parse(event_json, /*cb=*/nullptr,
                                                /*allow_exceptions=*/false);
  if (parsed.is_discarded()) {
    return absl::InvalidArgumentError("Failed to parse json");
  }
  if (!parsed.is_array()) {
    return absl::InvalidArgumentError("Invalid json");
  }
  LOG(INFO) << "Got " << parsed.size() << " events";

  events.reserve(parsed.size());
  for (const auto& parsed_event : parsed) {
    if (absl::StatusOr<Event> event = CreateEvent(parse_config, parsed_event);
        event.ok()) {
      events.push_back(*event);
    } else {
      LOG(ERROR) << "Failed to create event: " << event.status();
      return event.status();
    }
  }
  LOG(INFO) << "Parsed " << events.size() << " events";
  return events;
}

}  // namespace milotic
