#include "redfish_to_uhm_trie.hpp"

#include <memory>
#include <string>

#include <gtest/gtest.h>
#include "redfish_to_uhm_mapping.pb.h"
#include "redfish_to_uhm_mapping_value.hpp"

namespace devpath_plugin {
namespace {

TEST(RedfishToUhmTrieTest, BasicInsertAndGetMappingFromUrl) {
  RedfishToUhmTrie trie;

  auto val1 = std::make_shared<RedfishToUhmMappingValue>();
  val1->uhm_monitored_component_key.set_barepath("/phys/DC_SCM:device:hoth");
  val1->redfish_expose_config.set_expose_oem_google_devpath(true);
  val1->redfish_expose_config.set_set_plc_as_placeholder(false);
  val1->redfish_expose_config.set_embedded_location_context("hoth_context");

  Key insert_key1;
  insert_key1.set_redfish_url_pattern("/redfish/v1/RootOfTrustCollection/Hoth");
  trie.Insert(insert_key1, val1);

  Key lookup_key;
  lookup_key.set_redfish_url_pattern("/redfish/v1/RootOfTrustCollection/Hoth");

  std::shared_ptr<const RedfishToUhmMappingValue> found =
      trie.GetMappingFromUrl(lookup_key);
  ASSERT_NE(found, nullptr);
  EXPECT_EQ(found->uhm_monitored_component_key.barepath(),
            "/phys/DC_SCM:device:hoth");
  EXPECT_TRUE(found->redfish_expose_config.expose_oem_google_devpath());
  EXPECT_FALSE(found->redfish_expose_config.set_plc_as_placeholder());
  EXPECT_EQ(found->redfish_expose_config.embedded_location_context(),
            "hoth_context");
}

TEST(RedfishToUhmTrieTest, SegmentSeparation) {
  RedfishToUhmTrie trie;

  auto val1 = std::make_shared<RedfishToUhmMappingValue>();
  val1->uhm_monitored_component_key.set_barepath("/phys/diorite1");

  auto val2 = std::make_shared<RedfishToUhmMappingValue>();
  val2->uhm_monitored_component_key.set_barepath("/phys/diorite2");

  Key insert_key1;
  insert_key1.set_redfish_url_pattern("/redfish/v1/Chassis/Diorite_1");
  trie.Insert(insert_key1, val1);

  Key insert_key2;
  insert_key2.set_redfish_url_pattern("/redfish/v1/Chassis/Diorite_2");
  trie.Insert(insert_key2, val2);

  // Exact lookups
  Key lookup_key_1;
  lookup_key_1.set_redfish_url_pattern("/redfish/v1/Chassis/Diorite_1");
  std::shared_ptr<const RedfishToUhmMappingValue> found1 =
      trie.GetMappingFromUrl(lookup_key_1);
  ASSERT_NE(found1, nullptr);
  EXPECT_EQ(found1->uhm_monitored_component_key.barepath(), "/phys/diorite1");

  Key lookup_key_2;
  lookup_key_2.set_redfish_url_pattern("/redfish/v1/Chassis/Diorite_2");
  std::shared_ptr<const RedfishToUhmMappingValue> found2 =
      trie.GetMappingFromUrl(lookup_key_2);
  ASSERT_NE(found2, nullptr);
  EXPECT_EQ(found2->uhm_monitored_component_key.barepath(), "/phys/diorite2");

  // Prefix prefix checks (partial matches)
  Key lookup_key_prefix;
  lookup_key_prefix.set_redfish_url_pattern("/redfish/v1/Chassis");
  EXPECT_EQ(trie.GetMappingFromUrl(lookup_key_prefix), nullptr);

  Key lookup_key_extra;
  lookup_key_extra.set_redfish_url_pattern(
      "/redfish/v1/Chassis/Diorite_1/Extra");
  EXPECT_EQ(trie.GetMappingFromUrl(lookup_key_extra), nullptr);
}

TEST(RedfishToUhmTrieTest, RegexLegMatching) {
  RedfishToUhmTrie trie;

  auto val_regex = std::make_shared<RedfishToUhmMappingValue>();
  val_regex->uhm_monitored_component_key.set_barepath("/phys/any_dimm");

  Key insert_key_regex;
  insert_key_regex.set_redfish_url_pattern(
      "/redfish/v1/Systems/system1/Memory/dimm[0-9]+");
  trie.Insert(insert_key_regex, val_regex);

  // Matches regex pattern
  Key lookup_key_1;
  lookup_key_1.set_redfish_url_pattern(
      "/redfish/v1/Systems/system1/Memory/dimm5");
  auto found1 = trie.GetMappingFromUrl(lookup_key_1);
  ASSERT_NE(found1, nullptr);
  EXPECT_EQ(found1->uhm_monitored_component_key.barepath(), "/phys/any_dimm");

  // Matches regex pattern with a different digit
  Key lookup_key_2;
  lookup_key_2.set_redfish_url_pattern(
      "/redfish/v1/Systems/system1/Memory/dimm123");
  auto found2 = trie.GetMappingFromUrl(lookup_key_2);
  ASSERT_NE(found2, nullptr);
  EXPECT_EQ(found2->uhm_monitored_component_key.barepath(), "/phys/any_dimm");

  // Does not match regex pattern (non-digit suffix)
  Key lookup_key_fail;
  lookup_key_fail.set_redfish_url_pattern(
      "/redfish/v1/Systems/system1/Memory/dimmabc");
  auto found_fail = trie.GetMappingFromUrl(lookup_key_fail);
  EXPECT_EQ(found_fail, nullptr);
}

TEST(RedfishToUhmTrieTest, ExactMatchTakesPrecedenceOverRegex) {
  RedfishToUhmTrie trie;

  auto val_exact = std::make_shared<RedfishToUhmMappingValue>();
  val_exact->uhm_monitored_component_key.set_barepath("/phys/dimm5_special");

  auto val_regex = std::make_shared<RedfishToUhmMappingValue>();
  val_regex->uhm_monitored_component_key.set_barepath("/phys/dimm_generic");

  Key insert_generic;
  insert_generic.set_redfish_url_pattern(
      "/redfish/v1/Systems/system1/Memory/dimm[0-9]+");
  trie.Insert(insert_generic, val_regex);

  Key insert_special;
  insert_special.set_redfish_url_pattern(
      "/redfish/v1/Systems/system1/Memory/dimm5");
  trie.Insert(insert_special, val_exact);

  // Exact match matches val_exact
  Key lookup_special;
  lookup_special.set_redfish_url_pattern(
      "/redfish/v1/Systems/system1/Memory/dimm5");
  auto found_special = trie.GetMappingFromUrl(lookup_special);
  ASSERT_NE(found_special, nullptr);
  EXPECT_EQ(found_special->uhm_monitored_component_key.barepath(),
            "/phys/dimm5_special");

  // Other match falls back to generic regex
  Key lookup_generic;
  lookup_generic.set_redfish_url_pattern(
      "/redfish/v1/Systems/system1/Memory/dimm6");
  auto found_generic = trie.GetMappingFromUrl(lookup_generic);
  ASSERT_NE(found_generic, nullptr);
  EXPECT_EQ(found_generic->uhm_monitored_component_key.barepath(),
            "/phys/dimm_generic");
}

TEST(RedfishToUhmTrieTest, RegexDuplicateInsertionReusesNode) {
  RedfishToUhmTrie trie;

  auto val1 = std::make_shared<RedfishToUhmMappingValue>();
  val1->uhm_monitored_component_key.set_barepath("/phys/dimm_generic_1");

  auto val2 = std::make_shared<RedfishToUhmMappingValue>();
  val2->uhm_monitored_component_key.set_barepath("/phys/dimm_generic_2");

  Key insert_key;
  insert_key.set_redfish_url_pattern(
      "/redfish/v1/Systems/system1/Memory/dimm[0-9]+");

  trie.Insert(insert_key, val1);
  // Re-insert same pattern to verify overwrite/reuse
  trie.Insert(insert_key, val2);

  Key lookup_key;
  lookup_key.set_redfish_url_pattern(
      "/redfish/v1/Systems/system1/Memory/dimm5");
  auto found = trie.GetMappingFromUrl(lookup_key);
  ASSERT_NE(found, nullptr);
  EXPECT_EQ(found->uhm_monitored_component_key.barepath(),
            "/phys/dimm_generic_2");
}

TEST(RedfishToUhmTrieTest, EmptyPatternLegLookupReturnsNull) {
  RedfishToUhmTrie trie;
  Key lookup_empty;
  lookup_empty.set_redfish_url_pattern("");
  EXPECT_EQ(trie.GetMappingFromUrl(lookup_empty), nullptr);
}

}  // namespace
}  // namespace devpath_plugin
