#include "tlbmc/redfish/routes/debug.h"

#include <algorithm>
#include <array>
#include <cstddef>
#include <functional>
#include <string>
#include <string_view>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/functional/bind_front.h"
#include "absl/log/log.h"
#include "absl/strings/str_cat.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
#include "tlbmc/redfish/app.h"
#include "tlbmc/redfish/request.h"
#include "tlbmc/redfish/response.h"
#include "tlbmc/store/store.h"

namespace milotic_tlbmc::debug {

namespace {

constexpr std::array<const char*, 4> kResources = {"App", "Scheduler", "Store",
                                                   "HftService"};

void HandleDebugStoreResource(const RedfishApp& app, const RedfishRequest& req,
                              RedfishResponse& resp) {
  DLOG(INFO) << "HandleDebugStoreResource";
  resp.SetKeyInJsonBody("/@odata.id", "/redfish/tlbmc/Debug/Store");
  resp.SetKeyInJsonBody("/@odata.type",
                        "#TlbmcDebugStore.v1_0_0.TlbmcDebugStore");
  resp.SetKeyInJsonBody("/Name", "tlbmc");
  resp.SetKeyInJsonBody("/Description", "Detailed view of tlBMC store.");

  const Store& store = *app.GetStore();
  nlohmann::json store_json = store.ToJson();
  resp.SetKeyInJsonBody("/Store", store_json);
}

void HandleDebugResource(const RedfishApp& app, const RedfishRequest& req,
                         RedfishResponse& resp) {
  DLOG(INFO) << "HandleDebugResource";
  resp.SetKeyInJsonBody("/@odata.id", "/redfish/tlbmc/Debug");
  resp.SetKeyInJsonBody("/@odata.type",
                        "#TlBMCDebugEndpoint.v1_0_0.TlBMCDebugEndpoint");
  resp.SetKeyInJsonBody("/Name", "tlbmc");
  resp.SetKeyInJsonBody("/Description", "Gets tlBMC debug views.");
  for (const auto& resource : kResources) {
    nlohmann::json::object_t resource_json;
    resource_json["@odata.id"] =
        absl::StrCat("/redfish/tlbmc/Debug/", resource);
    resp.SetKeyInJsonBody(absl::StrCat("/", resource), resource_json);
  }
}

void HandleSchedulerResource(const RedfishApp& app, const RedfishRequest& req,
                             RedfishResponse& resp) {
  DLOG(INFO) << "HandleSchedulerResource";
  resp.SetKeyInJsonBody("/@odata.id", "/redfish/tlbmc/Debug/Scheduler");
  resp.SetKeyInJsonBody("/@odata.type",
                        "#TlbmcDebugScheduler.v1_0_0.TlbmcDebugScheduler");
  resp.SetKeyInJsonBody("/Name", "Scheduler");
  resp.SetKeyInJsonBody("/Description", "Detailed view of tlBMC scheduler.");
  resp.SetKeyInJsonBody("/SchedulerStats", app.GetStore()->GetSchedulerStats());
}

void HandleAppResource(const RedfishApp& app, const RedfishRequest& req,
                       RedfishResponse& resp) {
  DLOG(INFO) << "HandleDebugAppResource";
  resp.SetKeyInJsonBody("/@odata.id", "/redfish/tlbmc/Debug/App");
  resp.SetKeyInJsonBody("/@odata.type", "#TlbmcDebugApp.v1_0_0.TlbmcDebugApp");
  resp.SetKeyInJsonBody("/Name", "App Debug");
  resp.SetKeyInJsonBody("/Description", "Detailed view of tlBMC app.");

  auto sort_urls = [](const absl::flat_hash_map<std::string, size_t>& urls) {
    std::vector<std::string> urls_vector;
    for (const auto& [url, _] : urls) {
      urls_vector.push_back(url);
    }
    std::sort(urls_vector.begin(), urls_vector.end());
    return urls_vector;
  };

  // We dont want to change the underlying api as that would cause performance
  // issues elsewhere. The performance of this debug endpoint is not that
  // important and we can spend some time sorting here.
  resp.SetKeyInJsonBody("/OwnedUrls", sort_urls(app.GetOwnedUrls()));

  auto sort_subtrees = [](const absl::flat_hash_set<std::string>& subtrees) {
    std::vector<std::string> subtrees_vector(subtrees.begin(), subtrees.end());
    std::sort(subtrees_vector.begin(), subtrees_vector.end());
    return subtrees_vector;
  };

  resp.SetKeyInJsonBody("/OwnedSubtrees",
                        sort_subtrees(app.GetOwnedSubtrees()));
}

void HandleHftServiceResource(const RedfishApp& app, const RedfishRequest& req,
                              RedfishResponse& resp) {
  DLOG(INFO) << "HandleHftServiceResource";
  resp.SetKeyInJsonBody("/@odata.id", "/redfish/tlbmc/Debug/HftService");
  resp.SetKeyInJsonBody("/@odata.type",
                        "#TlbmcDebugHftService.v1_0_0.TlbmcDebugHftService");
  resp.SetKeyInJsonBody("/Name", "HftService");
  resp.SetKeyInJsonBody("/Description", "Detailed view of HftService.");
  resp.SetKeyInJsonBody("/HftService", app.GetHftService()->ToJson());
}

}  // namespace

void RegisterRoutes(RedfishApp& app) {
  TLBMC_ROUTE(app, "/redfish/tlbmc/Debug/")
      .methods(boost::beast::http::verb::get)(
          absl::bind_front(HandleDebugResource, std::cref(app)));

  TLBMC_ROUTE(app, "/redfish/tlbmc/Debug/App/")
      .methods(boost::beast::http::verb::get)(
          absl::bind_front(HandleAppResource, std::cref(app)));

  TLBMC_ROUTE(app, "/redfish/tlbmc/Debug/Store/")
      .methods(boost::beast::http::verb::get)(
          absl::bind_front(HandleDebugStoreResource, std::cref(app)));

  TLBMC_ROUTE(app, "/redfish/tlbmc/Debug/Scheduler/")
      .methods(boost::beast::http::verb::get)(
          absl::bind_front(HandleSchedulerResource, std::cref(app)));

  TLBMC_ROUTE(app, "/redfish/tlbmc/Debug/HftService/")
      .methods(boost::beast::http::verb::get)(
          absl::bind_front(HandleHftServiceResource, std::cref(app)));
}

}  // namespace milotic_tlbmc::debug
