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

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

#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*, 3> kResources = {"App", "Scheduler", "Store"};

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_set<std::string>& urls) {
    std::vector<std::string> urls_vector(urls.begin(), urls.end());
    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("/SupportedUrls", sort_urls(app.GetSupportedUrls()));
  resp.SetKeyInJsonBody("/OwnedUrls", sort_urls(app.GetOwnedUrls()));
}

}  // 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)));
}

}  // namespace milotic_tlbmc::debug
