#include <fstream>
#include <functional>
#include <memory>
#include <string>
#include <string_view>
#include <system_error>
#include <utility>

#include <gmock/gmock.h>  // IWYU pragma: keep
#include <gtest/gtest.h>  // IWYU pragma: keep

#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "boost/asio/io_context.hpp"  // NOLINT
#include "boost/beast/http/status.hpp"  // NOLINT
#include "boost/beast/http/verb.hpp"  // NOLINT
#include "redfish_devpath_injector.hpp"
#include "app.hpp"
#include "app_singleton.hpp"
#include "http_request.hpp"
#include "http_response.hpp"
#include "routing.hpp"
#include "async_resp.hpp"
#include "macros.hpp"
#include "query.hpp"
#include <nlohmann/json.hpp>

// IWYU pragma: no_include <gtest/gtest-message.h>
// IWYU pragma: no_include <gtest/gtest-test-part.h>
// IWYU pragma: no_include "gtest/gtest_pred_impl.h"
// IWYU pragma: no_include <gmock/gmock-matchers.h>
// IWYU pragma: no_include <gmock/gmock-more-matchers.h>
// IWYU pragma: no_include <gtest/gtest-matchers.h>

namespace crow {
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;
}

using ::testing::Eq;
using ::testing::IsEmpty;
using ::testing::Pointee;
using ::testing::UnorderedElementsAre;

TEST(GetRoutes, TestEmptyRoutes) {
  App app(/*allowSessionEmpty=*/true);
  app.validate();

  EXPECT_THAT(app.getRoutes(), IsEmpty());
}

// Tests that static urls are correctly passed
TEST(GetRoutes, TestOneRoute) {
  App app(/*allowSessionEmpty=*/true);

  BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });

  // TODO: "/" doesn't get reported in |getRoutes| today. Uncomment this once
  // it is fixed
  // EXPECT_THAT(app.getRoutes(),
  // testing::ElementsAre(Pointee(Eq("/"))));
}

// Tests that static urls are correctly passed
TEST(GetRoutes, TestlotsOfRoutes) {
  App app(/*allowSessionEmpty=*/true);
  BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
  BMCWEB_ROUTE(app, "/foo")([]() { return boost::beast::http::status::ok; });
  BMCWEB_ROUTE(app, "/bar")([]() { return boost::beast::http::status::ok; });
  BMCWEB_ROUTE(app, "/baz")([]() { return boost::beast::http::status::ok; });
  BMCWEB_ROUTE(app, "/boo")([]() { return boost::beast::http::status::ok; });
  BMCWEB_ROUTE(app, "/moo")([]() { return boost::beast::http::status::ok; });

  app.validate();

  // TODO: "/" doesn't get reported in |getRoutes| today. Uncomment this once
  // it is fixed
  EXPECT_THAT(app.getRoutes(),
              UnorderedElementsAre(
                  // Pointee(Eq("/")),
                  Pointee(Eq("/foo")), Pointee(Eq("/bar")), Pointee(Eq("/baz")),
                  Pointee(Eq("/boo")), Pointee(Eq("/moo"))));
}
}  // namespace

TEST(AppDevpathInjectorTest, InjectExpandRequests) {
  std::string config_content = R"pb(
    redfish_to_uhm_mapping {
      key { redfish_url_pattern: "/redfish/v1/Chassis/ChassisA" }
      uhm_monitored_component_key { barepath: "/phys/ChassisA" }
      redfish_expose_config {
        expose_oem_google_devpath: true
        set_plc_as_placeholder: false
      }
    }
    redfish_to_uhm_mapping {
      key {
        redfish_url_pattern:
            "/redfish/v1/Chassis/ChassisA/ThermalSubsystem/Fans/fan0"
      }
      uhm_monitored_component_key { barepath: "/phys/ChassisA/fan0" }
      redfish_expose_config {
        expose_oem_google_devpath: true
        set_plc_as_placeholder: false
      }
    }
  )pb";
  std::string config_path =
      WriteTmpFile("app_expand_config.textproto", config_content);

  // Instantiate the injector at the main/test function level
  absl::StatusOr<std::unique_ptr<
      devpath_plugin::RedfishDevpathInjector>> injector =
          devpath_plugin::RedfishDevpathInjector::Create(config_path);
  ASSERT_TRUE(injector.ok());

  // Initialize App and pass the raw pointer of the injector
  auto io =
      std::make_shared<boost::asio::io_context>();
  App app(true, io, nullptr, (*injector).get());
  ASSERT_EQ(app.GetDevpathInjector(), (*injector).get());

  crow::globalBmcWebApp = &app;

  // Track if sub-route plugins ran
  bool chassis_plugin_called = false;
  bool fan_plugin_called = false;

  // Register routes on the app.
  BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>")
      .methods(boost::beast::http::verb::get)(
          [&app](const Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& /*chassisId*/) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }
            asyncResp->res.jsonValue = {
                {"@odata.id", "/redfish/v1/Chassis/ChassisA"},
                {"Id", "ChassisA"},
                {"Name", "ChassisA"},
                {"ThermalSubsystem",
                 {{"@odata.id",
                   "/redfish/v1/Chassis/ChassisA/ThermalSubsystem"}}}
            };
          });

  // Use REDFISH_HANDLER_APPEND to inject a plugin on the chassis route
  REDFISH_HANDLER_APPEND(
      "/redfish/v1/Chassis/<str>", boost::beast::http::verb::get,
      [&chassis_plugin_called](
          const Request& /*req*/,
          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
          const std::string& /*chassisId*/) {
        chassis_plugin_called = true;
        asyncResp->res.jsonValue["ChassisPluginIndicator"] =
            "chassis_plugin_worked";
      });

  BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ThermalSubsystem")
      .methods(boost::beast::http::verb::get)(
          [&app](const Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& /*chassisId*/) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }
            asyncResp->res.jsonValue = {
                {"@odata.id", "/redfish/v1/Chassis/ChassisA/ThermalSubsystem"},
                {"Id", "ThermalSubsystem"},
                {"Name", "Thermal Subsystem"},
                {"Fans",
                 {{"@odata.id",
                   "/redfish/v1/Chassis/ChassisA/ThermalSubsystem/Fans"}}}
            };
          });

  BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ThermalSubsystem/Fans")
      .methods(boost::beast::http::verb::get)(
          [&app](const Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& /*chassisId*/) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }
            asyncResp->res.jsonValue = {
                {"@odata.id",
                 "/redfish/v1/Chassis/ChassisA/ThermalSubsystem/Fans"},
                {"Members",
                 {{{"@odata.id",
                    "/redfish/v1/Chassis/ChassisA/ThermalSubsystem/Fans/"
                    "fan0"}}}},
                {"Members@odata.count", 1},
                {"Name", "Fan Collection"}
            };
          });

  BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ThermalSubsystem/Fans/<str>")
      .methods(boost::beast::http::verb::get)(
          [&app](const Request& req,
                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                 const std::string& /*chassisId*/,
                 const std::string& /*fanId*/) {
            if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
              return;
            }
            asyncResp->res.jsonValue = {
                {"@odata.id",
                 "/redfish/v1/Chassis/ChassisA/ThermalSubsystem/Fans/fan0"},
                {"Id", "fan0"},
                {"Name", "fan0"}
            };
          });

  // Use REDFISH_HANDLER_APPEND to inject a plugin on the fan endpoint
  REDFISH_HANDLER_APPEND(
      "/redfish/v1/Chassis/<str>/ThermalSubsystem/Fans/<str>",
      boost::beast::http::verb::get,
      [&fan_plugin_called](
          const Request& /*req*/,
          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
          const std::string& /*chassisId*/, const std::string& /*fanId*/) {
        fan_plugin_called = true;
        asyncResp->res.jsonValue["FanPluginIndicator"] =
            "fan_plugin_worked";
      });

  app.validate();

  // Create expand request
  std::error_code ec;
  Request req(
      {boost::beast::http::verb::get,
       "/redfish/v1/Chassis/ChassisA?$expand=*($levels=3)", 11},
      ec);
  ASSERT_FALSE(ec);

  // Capture final response
  nlohmann::json final_response_json;
  boost::beast::http::status final_status =
      boost::beast::http::status::unknown;
  bool completed = false;

  {
    auto asyncResp =
        std::make_shared<bmcweb::AsyncResp>();
    asyncResp->res.setCompleteRequestHandler(
        [&final_response_json, &final_status, &completed](Response& res) {
          final_response_json = res.jsonValue;
          final_status = res.result();
          completed = true;
        });

    app.handle(req, asyncResp);
  }  // asyncResp count drops to 0, destructor is invoked, executing all
     // query param and injector logic.

  ASSERT_TRUE(completed);
  EXPECT_TRUE(chassis_plugin_called);
  EXPECT_TRUE(fan_plugin_called);
  EXPECT_EQ(final_status, boost::beast::http::status::ok);

  nlohmann::json expected = nlohmann::json::parse(R"json(
    {
      "@odata.id": "/redfish/v1/Chassis/ChassisA",
      "ChassisPluginIndicator": "chassis_plugin_worked",
      "Id": "ChassisA",
      "Location": {
        "Oem": {
          "Google": {
            "Devpath": "/phys/ChassisA"
          }
        },
        "PartLocation": {
          "ServiceLabel": "ChassisA"
        }
      },
      "Name": "ChassisA",
      "ThermalSubsystem": {
        "@odata.id": "/redfish/v1/Chassis/ChassisA/ThermalSubsystem",
        "Fans": {
          "@odata.id": "/redfish/v1/Chassis/ChassisA/ThermalSubsystem/Fans",
          "Members": [
            {
              "@odata.id": "/redfish/v1/Chassis/ChassisA/ThermalSubsystem/Fans/fan0",
              "FanPluginIndicator": "fan_plugin_worked",
              "Id": "fan0",
              "Location": {
                "Oem": {
                  "Google": {
                    "Devpath": "/phys/ChassisA/fan0"
                  }
                },
                "PartLocation": {
                  "ServiceLabel": "fan0"
                },
                "PartLocationContext": "ChassisA"
              },
              "Name": "fan0"
            }
          ],
          "Members@odata.count": 1,
          "Name": "Fan Collection"
        },
        "Id": "ThermalSubsystem",
        "Name": "Thermal Subsystem"
      }
    }
  )json");

  EXPECT_EQ(final_response_json, expected);
}
}  // namespace crow

