#include "redfish_devpath_injector.hpp"

#include <fstream>
#include <memory>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "boost/beast/http/status.hpp"  // NOLINT
#include "boost/beast/http/verb.hpp"  // NOLINT
#include "http_request.hpp"
#include "http_response.hpp"
#include <nlohmann/json.hpp>

using ::testing::status::StatusIs;

namespace devpath_plugin {
namespace {

std::string WriteTmpFile(std::string_view name, std::string_view content) {
  std::string path = absl::StrCat(testing::TempDir(), "/", name);
  std::ofstream out(path);
  out << content;
  out.close();
  return path;
}

crow::Request CreateRequest(
    std::string_view path,
    boost::beast::http::verb method = boost::beast::http::verb::get) {
  std::error_code ec;
  crow::Request req(std::string_view(""), ec);
  req.set_method(method);
  req.target(path);
  return req;
}

TEST(RedfishDevpathInjectorTest, LoadValidConfigSuccess) {
  std::string config_content = R"pb(
    redfish_to_uhm_mapping {
      key { redfish_url_pattern: "/redfish/v1/RootOfTrustCollection/RotA" }
      uhm_monitored_component_key { barepath: "/phys/BoardA:device:rot_a" }
      redfish_expose_config {
        expose_oem_google_devpath: true
        set_plc_as_placeholder: false
        embedded_location_context: "rot_context_a"
      }
    }
  )pb";
  std::string config_path =
      WriteTmpFile("valid_config.textproto", config_content);

  ASSERT_OK(RedfishDevpathInjector::Create(config_path).status());
}

TEST(RedfishDevpathInjectorTest, LoadInvalidConfigReturnsError) {
  std::string invalid_config_path =
      WriteTmpFile("invalid_config.textproto", "invalid_content");
  EXPECT_THAT(RedfishDevpathInjector::Create(invalid_config_path),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(RedfishDevpathInjectorTest, NonExistentConfigReturnsError) {
  EXPECT_THAT(
      RedfishDevpathInjector::Create("/path/to/non_existent_file.textproto"),
      StatusIs(absl::StatusCode::kNotFound));
}

TEST(RedfishDevpathInjectorTest, InjectValidMappingSuccess) {
  std::string config_content = R"pb(
    redfish_to_uhm_mapping {
      key { redfish_url_pattern: "/redfish/v1/RootOfTrustCollection/RotA" }
      uhm_monitored_component_key { barepath: "/phys/BoardA:device:rot_a" }
      redfish_expose_config {
        expose_oem_google_devpath: true
        set_plc_as_placeholder: false
        embedded_location_context: "rot_context_a"
      }
    }
    redfish_to_uhm_mapping {
      key { redfish_url_pattern: "/redfish/v1/Chassis/ChassisA" }
      uhm_monitored_component_key { barepath: "/phys/BoardA" }
      redfish_expose_config {
        expose_oem_google_devpath: false
        set_plc_as_placeholder: true
      }
    }
    redfish_to_uhm_mapping {
      key { redfish_url_pattern: "/redfish/v1/Chassis/ChassisB" }
      uhm_monitored_component_key { barepath: "/phys/BoardA" }
      redfish_expose_config {
        expose_oem_google_devpath: false
        set_plc_as_placeholder: false
      }
    }
  )pb";
  std::string config_path =
      WriteTmpFile("injectable_config.textproto", config_content);

  absl::StatusOr<std::unique_ptr<RedfishDevpathInjector>> injector =
      RedfishDevpathInjector::Create(config_path);
  ASSERT_OK(injector.status());

  // Test Component 1 with :device:
  {
    crow::Request req = CreateRequest("/redfish/v1/RootOfTrustCollection/RotA");
    crow::Response res;
    res.result(boost::beast::http::status::ok);

    (*injector)->Inject(req, res);

    const nlohmann::json& json = res.jsonValue;
    EXPECT_EQ(json["Location"]["PartLocation"]["ServiceLabel"], "rot_a");
    EXPECT_EQ(json["Location"]["PartLocationContext"], "BoardA");
    EXPECT_EQ(json["Location"]["Oem"]["Google"]["Devpath"],
              "/phys/BoardA:device:rot_a");
    EXPECT_EQ(json["Location"]["Oem"]["Google"]["EmbeddedLocationContext"],
              "rot_context_a");
  }

  // Test Component 2 without :device: and with placeholder plc
  {
    crow::Request req = CreateRequest("/redfish/v1/Chassis/ChassisA");
    crow::Response res;
    res.result(boost::beast::http::status::ok);

    (*injector)->Inject(req, res);

    nlohmann::json json = res.jsonValue;
    EXPECT_EQ(json["Location"]["PartLocation"]["ServiceLabel"], "BoardA");
    EXPECT_EQ(json["Location"]["PartLocationContext"],
              "PlaceholderAndShouldNotBeUsed");

    EXPECT_FALSE(json["Location"]["Oem"]["Google"].contains("Devpath"));
    EXPECT_FALSE(
        json["Location"]["Oem"]["Google"].contains("EmbeddedLocationContext"));
  }

  // Test Component 3 where PLC is empty and shouldn't appear
  {
    crow::Request req = CreateRequest("/redfish/v1/Chassis/ChassisB");
    crow::Response res;
    res.result(boost::beast::http::status::ok);

    (*injector)->Inject(req, res);

    nlohmann::json json = res.jsonValue;
    EXPECT_EQ(json["Location"]["PartLocation"]["ServiceLabel"], "BoardA");
    EXPECT_FALSE(json["Location"].contains("PartLocationContext"));
  }
}

TEST(RedfishDevpathInjectorTest, InjectNonGetRequestReturnsNoOp) {
  std::string config_content = R"pb(
    redfish_to_uhm_mapping {
      key { redfish_url_pattern: "/redfish/v1/RootOfTrustCollection/RotA" }
      uhm_monitored_component_key { barepath: "/phys/BoardA:device:rot_a" }
    }
  )pb";
  std::string config_path =
      WriteTmpFile("nonget_config.textproto", config_content);

  absl::StatusOr<std::unique_ptr<RedfishDevpathInjector>> injector =
      RedfishDevpathInjector::Create(config_path);
  ASSERT_OK(injector.status());

  crow::Request req = CreateRequest("/redfish/v1/RootOfTrustCollection/RotA",
                                    boost::beast::http::verb::post);
  crow::Response res;
  res.result(boost::beast::http::status::ok);

  (*injector)->Inject(req, res);

  EXPECT_TRUE(res.jsonValue.empty());
}

TEST(RedfishDevpathInjectorTest, InjectNonOkStatusReturnsNoOp) {
  std::string config_content = R"pb(
    redfish_to_uhm_mapping {
      key { redfish_url_pattern: "/redfish/v1/RootOfTrustCollection/RotA" }
      uhm_monitored_component_key { barepath: "/phys/BoardA:device:rot_a" }
    }
  )pb";
  std::string config_path =
      WriteTmpFile("nonok_config.textproto", config_content);

  absl::StatusOr<std::unique_ptr<RedfishDevpathInjector>> injector =
      RedfishDevpathInjector::Create(config_path);
  ASSERT_OK(injector.status());

  crow::Request req = CreateRequest("/redfish/v1/RootOfTrustCollection/RotA");
  crow::Response res;
  res.result(boost::beast::http::status::not_found);

  (*injector)->Inject(req, res);

  EXPECT_TRUE(res.jsonValue.empty());
}

TEST(RedfishDevpathInjectorTest, InjectNonExistentUrlReturnsNoOp) {
  std::string config_content = R"pb(
    redfish_to_uhm_mapping {
      key { redfish_url_pattern: "/redfish/v1/RootOfTrustCollection/RotA" }
      uhm_monitored_component_key { barepath: "/phys/BoardA:device:rot_a" }
    }
  )pb";
  std::string config_path =
      WriteTmpFile("nonexistent_config.textproto", config_content);

  absl::StatusOr<std::unique_ptr<RedfishDevpathInjector>> injector =
      RedfishDevpathInjector::Create(config_path);
  ASSERT_OK(injector.status());

  crow::Request req =
      CreateRequest("/redfish/v1/RootOfTrustCollection/DeviceB");
  crow::Response res;
  res.result(boost::beast::http::status::ok);

  (*injector)->Inject(req, res);

  EXPECT_TRUE(res.jsonValue.empty());
}

TEST(RedfishDevpathInjectorTest, InjectRegexMappingSuccess) {
  std::string config_content = R"pb(
    redfish_to_uhm_mapping {
      key {
        redfish_url_pattern: "/redfish/v1/Systems/system/Storage/StorageModuleA/Controllers/[0-9]+"
      }
      uhm_monitored_component_key {
        barepath: "/phys/SlotA:device:controller_a"
      }
      redfish_expose_config {
        expose_oem_google_devpath: true
        set_plc_as_placeholder: false
        embedded_location_context: "controller:0"
      }
    }
  )pb";
  std::string config_path =
      WriteTmpFile("regex_config.textproto", config_content);

  absl::StatusOr<std::unique_ptr<RedfishDevpathInjector>> injector =
      RedfishDevpathInjector::Create(config_path);
  ASSERT_OK(injector.status());

  // Test correct match
  {
    crow::Request req = CreateRequest(
        "/redfish/v1/Systems/system/Storage/StorageModuleA/Controllers/0");
    crow::Response res;
    res.result(boost::beast::http::status::ok);

    (*injector)->Inject(req, res);

    const nlohmann::json& json = res.jsonValue;
    EXPECT_EQ(json["Location"]["PartLocation"]["ServiceLabel"], "controller_a");
    EXPECT_EQ(json["Location"]["PartLocationContext"], "SlotA");
    EXPECT_EQ(json["Location"]["Oem"]["Google"]["Devpath"],
              "/phys/SlotA:device:controller_a");
    EXPECT_EQ(json["Location"]["Oem"]["Google"]["EmbeddedLocationContext"],
              "controller:0");
  }

  // Test path not fitting the regex
  {
    crow::Request req = CreateRequest(
        "/redfish/v1/Systems/system/Storage/StorageModuleA/Controllers/abc");
    crow::Response res;
    res.result(boost::beast::http::status::ok);

    (*injector)->Inject(req, res);

    EXPECT_TRUE(res.jsonValue.empty());
  }
}

}  // namespace
}  // namespace devpath_plugin
