#include "sse_plugin/event.h"

#include <string>

#include "quality/actions/offline/android/portable_protos/portable_message.h"
#include "gmock.h"
#include "gunit.h"
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "redfish_query_engine/protobuf/parse.h"
#include "proxy_config.pb.h"
#include "events.pb.h"
#include "vendor_events.pb.h"
#include "google/protobuf/repeated_ptr_field.h"

namespace milotic {
namespace {

using testing::AllOf;
using testing::Property;
using testing::SizeIs;
using testing::status::IsOkAndHolds;
using testing::status::StatusIs;

TEST(ParseRedfishEventTest, InvalidJson) {
  constexpr absl::string_view kEventJson = R"json(invalid-json)json";
  EventParseConfig parse_config;

  EXPECT_THAT(
      Event::ParseRedfishEvent(parse_config, kEventJson),
      StatusIs(absl::StatusCode::kInvalidArgument, "Failed to parse json"));
}

TEST(ParseRedfishEventTest, InvalidEventJsonNotArray) {
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": {"MessageSeverity": "OK", "EventId":
      "1"}})json";
  EventParseConfig parse_config;

  EXPECT_THAT(
      Event::ParseRedfishEvent(parse_config, kEventJson),
      StatusIs(
          absl::StatusCode::kInvalidArgument,
          "Invalid event json, Events should be an array with single element"));
}

TEST(ParseRedfishEventTest, InvalidEventJsonArraySizeZero) {
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": []})json";
  EventParseConfig parse_config;

  EXPECT_THAT(
      Event::ParseRedfishEvent(parse_config, kEventJson),
      StatusIs(
          absl::StatusCode::kInvalidArgument,
          "Invalid event json, Events should be an array with single element"));
}

TEST(ParseRedfishEventTest, InvalidEventJsonArraySizeGTOne) {
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "OK", "EventId":
      "1"}, {"MessageSeverity": "OK", "EventId": "2"}]})json";
  EventParseConfig parse_config;

  EXPECT_THAT(
      Event::ParseRedfishEvent(parse_config, kEventJson),
      StatusIs(
          absl::StatusCode::kInvalidArgument,
          "Invalid event json, Events should be an array with single element"));
}

TEST(ParseRedfishEventTest, SSEIdEventIdMismatch) {
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "OK", "EventId":
      "2"}]})json";
  EventParseConfig parse_config;

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       "EventId mismatch, Id: 1, Events[0][EventId]: 2"));
}

TEST(ParseRedfishEventTest, EventIdNotNumber) {
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "a","Events": [{"MessageSeverity": "OK", "EventId":
      "a"}]})json";
  EventParseConfig parse_config;

  EXPECT_THAT(
      Event::ParseRedfishEvent(parse_config, kEventJson),
      StatusIs(absl::StatusCode::kInvalidArgument, "EventId is not a number"));
}

TEST(ParseRedfishEventTest, InvalidMessageSev) {
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Invalid", "EventId":
      "1"}]})json";
  EventParseConfig parse_config;

  EXPECT_THAT(
      Event::ParseRedfishEvent(parse_config, kEventJson),
      StatusIs(absl::StatusCode::kInvalidArgument, "Invalid message severity"));
}

TEST(ParseRedfishEventTest, OkEvent) {
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "OK", "EventId":
      "1"}]})json";
  EventParseConfig parse_config;

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(
                  Contains(AllOf(Property(&Event::severity, EventSeverity::kOk),
                                 Property(&Event::event_id, 1)))));
}

TEST(ParseRedfishEventTest, WarningEvent) {
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1"}]})json";
  EventParseConfig parse_config;

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kWarning),
                        Property(&Event::event_id, 1)))));
}

TEST(ParseRedfishEventTest, CriticalEvent) {
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Critical",
      "EventId": "1"}]})json";
  EventParseConfig parse_config;

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kCritical),
                        Property(&Event::event_id, 1)))));
}

milotic_grpc_proxy::EventParse GetEventParseProtoWithOemPathReasonId() {
  return ecclesia::ParseTextAsProtoOrDie<milotic_grpc_proxy::EventParse>(R"pb(
    reason_id_parse: { oem_field_path: "/OriginOfCondition/Oem/Hpe/Faults" }
  )pb");
}

// Test various failure conditions on FindReasonId, such that event severity
// falls to MessageSeverity
TEST(FindReasonIdOemPathTest, EventWithInvalidReasonID) {
  // ReasonID should be int
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1", "OriginOfCondition": {"Oem": {"Hpe": {"Faults": [{"Reasons":
      [{"ReasonId": "302", "DateTime": "2023-05-12T01:51:50Z"}]}]}}}
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event = platforms_vbmc::VendorEvent();
  vendor_event.set_severity(platforms_vbmc::OtsEvent::SEVERITY_CRITICAL);
  vendor_event.set_reason_id(302);
  registry.emplace(302, vendor_event);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kWarning),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(FindReasonIdOemPathTest, EventWithInvalidDateTime1) {
  // DateTime should be string
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1", "OriginOfCondition": {"Oem": {"Hpe": {"Faults": [{"Reasons":
      [{"ReasonId": 302, "DateTime": 123}]}]}}}
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event = platforms_vbmc::VendorEvent();
  vendor_event.set_severity(platforms_vbmc::OtsEvent::SEVERITY_CRITICAL);
  vendor_event.set_reason_id(302);
  registry.emplace(302, vendor_event);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kWarning),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(FindReasonIdOemPathTest, EventWithInvalidDateTime2) {
  // DateTime should be valid
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1", "OriginOfCondition": {"Oem": {"Hpe": {"Faults": [{"Reasons":
      [{"ReasonId": "302", "DateTime": "2023-05-12T01:51:90Z"}]}]}}}
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event = platforms_vbmc::VendorEvent();
  vendor_event.set_severity(platforms_vbmc::OtsEvent::SEVERITY_CRITICAL);
  vendor_event.set_reason_id(302);
  registry.emplace(302, vendor_event);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kWarning),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(FindReasonIdOemPathTest, EventWithNoReasonId) {
  // No Reason ID in event
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1", "OriginOfCondition": {"Oem": {"Hpe": {"Faults": [{"Reasons":
      []}]}}}
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event = platforms_vbmc::VendorEvent();
  vendor_event.set_severity(platforms_vbmc::OtsEvent::SEVERITY_CRITICAL);
  vendor_event.set_reason_id(302);
  registry.emplace(302, vendor_event);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kWarning),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(FindReasonIdOemPathTest, EventWithReasonsNotArray) {
  // Reasons is not array
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1", "OriginOfCondition": {"Oem": {"Hpe": {"Faults": [{"Reasons":
      {}}]}}}
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event = platforms_vbmc::VendorEvent();
  vendor_event.set_severity(platforms_vbmc::OtsEvent::SEVERITY_CRITICAL);
  vendor_event.set_reason_id(302);
  registry.emplace(302, vendor_event);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kWarning),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(FindReasonIdOemPathTest, EventWithNoReasonsInFaults) {
  // No Reasons in Faults
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1", "OriginOfCondition": {"Oem": {"Hpe": {"Faults": []}}}
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event = platforms_vbmc::VendorEvent();
  vendor_event.set_severity(platforms_vbmc::OtsEvent::SEVERITY_CRITICAL);
  vendor_event.set_reason_id(302);
  registry.emplace(302, vendor_event);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kWarning),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(FindReasonIdOemPathTest, EventWithFaultsNotArray) {
  // Faults is not array
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1", "OriginOfCondition": {"Oem": {"Hpe": {"Faults": {}}}}
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event = platforms_vbmc::VendorEvent();
  vendor_event.set_severity(platforms_vbmc::OtsEvent::SEVERITY_CRITICAL);
  vendor_event.set_reason_id(302);
  registry.emplace(302, vendor_event);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kWarning),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(FindReasonIdOemPathTest, EventWithFaultPathNotPresent1) {
  // Faults path not present
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1", "OriginOfCondition": {"Oem": {"Hpe": {"Faults1": {}}}}
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event = platforms_vbmc::VendorEvent();
  vendor_event.set_severity(platforms_vbmc::OtsEvent::SEVERITY_CRITICAL);
  vendor_event.set_reason_id(302);
  registry.emplace(302, vendor_event);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kWarning),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(FindReasonIdOemPathTest, EventWithFaultPathNotPresent2) {
  // Faults path not present
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1", "OriginOfCondition": {"Oem": {"Hpe": {}}}
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event = platforms_vbmc::VendorEvent();
  vendor_event.set_severity(platforms_vbmc::OtsEvent::SEVERITY_CRITICAL);
  vendor_event.set_reason_id(302);
  registry.emplace(302, vendor_event);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kWarning),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(FindReasonIdOemPathTest, EventWithFaultPathNotPresent3) {
  // Faults path not present
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1", "OriginOfCondition": {"Oem": {"Hpe": []}}
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event = platforms_vbmc::VendorEvent();
  vendor_event.set_severity(platforms_vbmc::OtsEvent::SEVERITY_CRITICAL);
  vendor_event.set_reason_id(302);
  registry.emplace(302, vendor_event);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kWarning),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(FindReasonIdOemPathTest, EventWithFaultPathNotPresent4) {
  // Faults path not present
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1", "OriginOfCondition": {"Oem": []}
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event = platforms_vbmc::VendorEvent();
  vendor_event.set_severity(platforms_vbmc::OtsEvent::SEVERITY_CRITICAL);
  vendor_event.set_reason_id(302);
  registry.emplace(302, vendor_event);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kWarning),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(FindReasonIdOemPathTest, EventWithValidReasonID) {
  // Registry severity should be used instead of MessageSeverity
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1", "OriginOfCondition": {"Oem": {"Hpe": {"Faults": [{"Reasons":
      [{"ReasonId": 302, "DateTime": "2023-05-12T01:51:50Z"}]}]}}}
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event = platforms_vbmc::VendorEvent();
  vendor_event.set_severity(platforms_vbmc::OtsEvent::SEVERITY_CRITICAL);
  vendor_event.set_reason_id(302);
  registry.emplace(302, vendor_event);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(
      Event::ParseRedfishEvent(parse_config, kEventJson),
      IsOkAndHolds(Contains(AllOf(
          Property(&Event::severity, EventSeverity::kCritical),
          Property(&Event::event_id, 1), Property(&Event::reason_id, 302)))));
}

TEST(FindReasonIdOemPathTest, EventWithMultipleReasonID) {
  // Registry severity should be used of reason ID with max DateTime
  // even if severity of other reason is higher
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Ok", "EventId": "1",
      "OriginOfCondition": {"Oem": {"Hpe": {"Faults": [{"Reasons": [
      {"ReasonId": 302, "DateTime": "2023-05-12T01:51:50Z"},
      {"ReasonId": 303, "DateTime": "2023-05-13T01:51:50Z"}
      ]}]}}}
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event1 = platforms_vbmc::VendorEvent();
  vendor_event1.set_severity(platforms_vbmc::OtsEvent::SEVERITY_CRITICAL);
  vendor_event1.set_reason_id(302);
  registry.emplace(302, vendor_event1);
  auto vendor_event2 = platforms_vbmc::VendorEvent();
  vendor_event2.set_severity(platforms_vbmc::OtsEvent::SEVERITY_WARNING);
  vendor_event2.set_reason_id(303);
  registry.emplace(303, vendor_event2);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(
      Event::ParseRedfishEvent(parse_config, kEventJson),
      IsOkAndHolds(Contains(AllOf(
          Property(&Event::severity, EventSeverity::kWarning),
          Property(&Event::event_id, 1), Property(&Event::reason_id, 303)))));
}

TEST(FindReasonIdOemPathTest, EventWithReasonIdNotInRegistry) {
  // If reason ID is not found in registry fall back to MessageSeverity
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId":
      "1", "OriginOfCondition": {"Oem": {"Hpe": {"Faults": [{"Reasons":
      [{"ReasonId": 302, "DateTime": "2023-05-12T01:51:50Z"}]}]}}}
      }]})json";
  EventParseConfig parse_config = {.event_parse =
                                       GetEventParseProtoWithOemPathReasonId()};

  EXPECT_THAT(
      Event::ParseRedfishEvent(parse_config, kEventJson),
      IsOkAndHolds(Contains(AllOf(
          Property(&Event::severity, EventSeverity::kWarning),
          Property(&Event::event_id, 1), Property(&Event::reason_id, 302)))));
}

milotic_grpc_proxy::EventParse GetEventParseProtoWithMsgArgsReasonId() {
  return ecclesia::ParseTextAsProtoOrDie<milotic_grpc_proxy::EventParse>(R"pb(
    reason_id_parse: {
      message_args_index: {
        message_key: "ServiceEventGeneratedNoIndictment"
        message_arg_index: 1
      }
    }
  )pb");
}

TEST(FindReasonIdMessageArgsTest, EventWithInvalidMessageId) {
  // If MessageId is invalid and reason id parsing with message arg is set,
  // InvalidArgument error is returned
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{
      "MessageSeverity": "Critical", "EventId": "1", 
      "Message": "A service event has been generated against npar 0 for reason ID 1349.", 
      "MessageArgs":["0","1349"], 
      "MessageId":"ServiceEventGeneratedNoIndictment"
      }]})json";
  EventParseConfig parse_config = {.event_parse =
                                       GetEventParseProtoWithMsgArgsReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       "MessageId not in correct format"));
}

TEST(FindReasonIdMessageArgsTest, MessageArgIndexNotPresent) {
  // MessageSeverity will be used, since we're not able to find the reason ID
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{
      "MessageSeverity": "Critical", "EventId": "1", 
      "Message": "A service event has been generated against npar 0 for reason ID 1349.", 
      "MessageArgs":["1349"], 
      "MessageId":"H3Alert.1.1.ServiceEventGeneratedNoIndictment"
      }]})json";
  EventParseConfig parse_config = {.event_parse =
                                       GetEventParseProtoWithMsgArgsReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kCritical),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(FindReasonIdMessageArgsTest, MessageArgIndexNotInt) {
  // MessageSeverity will be used, since we're not able to find the reason ID
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{
      "MessageSeverity": "Critical", "EventId": "1", 
      "Message": "A service event has been generated against npar 0 for reason ID 1349.", 
      "MessageArgs":["0", "invalid"], 
      "MessageId":"H3Alert.1.1.ServiceEventGeneratedNoIndictment"
      }]})json";
  EventParseConfig parse_config = {.event_parse =
                                       GetEventParseProtoWithMsgArgsReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kCritical),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(FindReasonIdMessageArgsTest, EventWithValidReasonID) {
  // Registry severity should be used instead of MessageSeverity
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{
      "MessageSeverity": "Critical", "EventId": "1", 
      "Message": "A service event has been generated against npar 0 for reason ID 1349.", 
      "MessageArgs":["0","1349"], 
      "MessageId":"H3Alert.1.1.ServiceEventGeneratedNoIndictment"
      }]})json";
  absl::flat_hash_map<int, platforms_vbmc::VendorEvent> registry;
  auto vendor_event = platforms_vbmc::VendorEvent();
  vendor_event.set_severity(platforms_vbmc::OtsEvent::SEVERITY_WARNING);
  vendor_event.set_reason_id(1349);
  registry.emplace(1349, vendor_event);
  EventParseConfig parse_config = {
      .registry = registry,
      .event_parse = GetEventParseProtoWithMsgArgsReasonId()};

  EXPECT_THAT(
      Event::ParseRedfishEvent(parse_config, kEventJson),
      IsOkAndHolds(Contains(AllOf(
          Property(&Event::severity, EventSeverity::kWarning),
          Property(&Event::event_id, 1), Property(&Event::reason_id, 1349)))));
}

TEST(FindReasonIdMessageArgsTest, EventWithMissingMessageArgs) {
  // Registry severity should be used instead of MessageSeverity
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{
      "MessageSeverity": "Critical", "EventId": "1", 
      "Message": "A service event has been generated against npar 0 for reason ID 1349.", 
      "MessageId":"H3Alert.1.1.ServiceEventGeneratedNoIndictment"
      }]})json";
  EventParseConfig parse_config = {.event_parse =
                                       GetEventParseProtoWithMsgArgsReasonId()};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(Contains(
                  AllOf(Property(&Event::severity, EventSeverity::kCritical),
                        Property(&Event::event_id, 1),
                        Property(&Event::reason_id, kInvalidReasonId)))));
}

TEST(IgnoreEventsWOReasonIdTest, UseOkSeverity) {
  // If ignore w/o reasonId is set, use Ok severity if we cannot find reasonId
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{
      "MessageSeverity": "Critical", "EventId": "1", 
      "MessageId":"H3Alert.1.1.ServiceEventGeneratedNoIndictment"
      }]})json";
  milotic_grpc_proxy::EventParse proto_config;
  proto_config.set_ignore_event_sev_wo_reason_id(true);
  EventParseConfig parse_config = {.event_parse = proto_config};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(
                  Contains(AllOf(Property(&Event::severity, EventSeverity::kOk),
                                 Property(&Event::event_id, 1)))));
}

TEST(IgnoreEventsWOReasonIdTest, ReasonIdPresentRegistryEmpty) {
  // If we find reasonId but registry is empty/doesn't contain the reasonId we
  // use MessageSeverity
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{
      "MessageSeverity": "Critical", "EventId": "1", 
      "Message": "A service event has been generated against npar 0 for reason ID 1349.",
      "MessageArgs":["0","1349"], 
      "MessageId":"H3Alert.1.1.ServiceEventGeneratedNoIndictment"
      }]})json";
  milotic_grpc_proxy::EventParse proto_config =
      GetEventParseProtoWithMsgArgsReasonId();
  proto_config.set_ignore_event_sev_wo_reason_id(true);
  EventParseConfig parse_config = {.event_parse = proto_config};

  EXPECT_THAT(
      Event::ParseRedfishEvent(parse_config, kEventJson),
      IsOkAndHolds(Contains(AllOf(
          Property(&Event::severity, EventSeverity::kCritical),
          Property(&Event::event_id, 1), Property(&Event::reason_id, 1349)))));
}

TEST(FindMessageKeyTest, EventWithInvalidMessageId) {
  // If MessageId is invalid and ignore_message_keys is set,
  // InvalidArgument error is returned
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId": "1", 
      "MessageId": "LastEventIdTooOld"
      }]})json";
  RepeatedPtrField<std::string> ignore_list;
  ignore_list.Add("LastEventIdTooOld");
  milotic_grpc_proxy::EventParse proto_config;
  *proto_config.mutable_ignore_event_sev_message_keys() = ignore_list;
  EventParseConfig parse_config = {.event_parse = proto_config};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       "MessageId not in correct format"));
}

TEST(FindMessageKeyTest, EventWithMessageKeyInIgnoreList) {
  // OK severity should be used instead of MessageSeverity
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId": "1", 
      "MessageId": "H3Alert.1.1.LastEventIdTooOld"
      }]})json";
  RepeatedPtrField<std::string> ignore_list;
  ignore_list.Add("LastEventIdTooOld");
  milotic_grpc_proxy::EventParse proto_config;
  *proto_config.mutable_ignore_event_sev_message_keys() = ignore_list;
  EventParseConfig parse_config = {.event_parse = proto_config};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(
                  Contains(AllOf(Property(&Event::severity, EventSeverity::kOk),
                                 Property(&Event::event_id, 1)))));
}

TEST(FindMessagePrefixTest, EventWithInvalidMessageId) {
  // If MessageId is invalid and ignore_message_prefix is set,
  // InvalidArgument error is returned
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId": "1", 
      "MessageId": "ResourceStatusChangedWarning"
      }]})json";
  RepeatedPtrField<std::string> ignore_list;
  ignore_list.Add("ResourceEvent");
  milotic_grpc_proxy::EventParse proto_config;
  *proto_config.mutable_ignore_event_sev_message_prefix() = ignore_list;
  EventParseConfig parse_config = {.event_parse = proto_config};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       "MessageId not in correct format"));
}

TEST(FindMessagePrefixTest, EventWithMessagePrefixInIgnoreList) {
  // OK severity should be used instead of MessageSeverity
  constexpr absl::string_view kEventJson =
      R"json({"Id" : "1","Events": [{"MessageSeverity": "Warning", "EventId": "1", 
      "MessageId": "ResourceEvent.1.3.ResourceStatusChangedWarning"
      }]})json";
  RepeatedPtrField<std::string> ignore_list;
  ignore_list.Add("ResourceEvent");
  milotic_grpc_proxy::EventParse proto_config;
  *proto_config.mutable_ignore_event_sev_message_prefix() = ignore_list;
  EventParseConfig parse_config = {.event_parse = proto_config};

  EXPECT_THAT(Event::ParseRedfishEvent(parse_config, kEventJson),
              IsOkAndHolds(
                  Contains(AllOf(Property(&Event::severity, EventSeverity::kOk),
                                 Property(&Event::event_id, 1)))));
}

TEST(ParseReplayEventTest, EmptyResponse) {
  constexpr absl::string_view kEventJson;
  EventParseConfig parse_config;
  EXPECT_THAT(Event::ParseReplayEvents(parse_config, kEventJson),
              IsOkAndHolds(SizeIs(0)));
}

TEST(ParseReplayEventTest, InvalidJson) {
  constexpr absl::string_view kEventJson = R"json(invalid-json)json";
  EventParseConfig parse_config;
  EXPECT_THAT(
      Event::ParseReplayEvents(parse_config, kEventJson),
      StatusIs(absl::StatusCode::kInvalidArgument, "Failed to parse json"));
}

TEST(ParseReplayEventTest, NotArray) {
  constexpr absl::string_view kEventJson =
      R"json({"MessageSeverity": "Critical", "EventId": "1"})json";
  EventParseConfig parse_config;
  EXPECT_THAT(Event::ParseReplayEvents(parse_config, kEventJson),
              StatusIs(absl::StatusCode::kInvalidArgument, "Invalid json"));
}

TEST(ParseReplayEventTest, MultipleEvents) {
  constexpr absl::string_view kEventJson =
      R"json([{"MessageSeverity": "Critical", "EventId": "1"},
      {"MessageSeverity": "Critical", "EventId": "2"}])json";
  EventParseConfig parse_config;
  EXPECT_THAT(Event::ParseReplayEvents(parse_config, kEventJson),
              IsOkAndHolds(SizeIs(2)));
}

TEST(ParseReplayEventTest, OneInvalidEvent) {
  constexpr absl::string_view kEventJson =
      R"json([{"MessageSeverity": "Critical", "EventId": "1"},
      {"MessageSeverity": "Critical", "EventId": "a"}])json";
  EventParseConfig parse_config;
  EXPECT_THAT(
      Event::ParseReplayEvents(parse_config, kEventJson),
      StatusIs(absl::StatusCode::kInvalidArgument, "EventId is not a number"));
}

}  // namespace
}  // namespace milotic
