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

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

#include "absl/functional/bind_front.h"
#include "absl/status/statusor.h"
#include "absl/time/clock.h"
#include "nlohmann/json.hpp"
#include "topology_config.pb.h"
#include "tlbmc/redfish/app.h"
#include "tlbmc/redfish/request.h"
#include "tlbmc/redfish/response.h"
#include "tlbmc/redfish/routes/chassis.h"
#include "fru.pb.h"
#include "resource.pb.h"
#include "tlbmc/store/store.h"
#include "tlbmc/trace/tracer.h"

namespace milotic_tlbmc::all_chassis {

namespace {

using ::milotic_tlbmc::chassis::FillResponseWithFruData;

void HandleAllChassis(const RedfishApp& app, const RedfishRequest& req,
                      RedfishResponse& resp) {
  milotic_tlbmc::Tracer::GetInstance().AddRepeatedDatapoint(
      "Tlbmc-AllChassis-FetchState-Begin", absl::Now());
  const Store& store = *app.GetStore();
  absl::StatusOr<std::vector<std::string>> configs = store.GetAllConfigNames();
  milotic_tlbmc::Tracer::GetInstance().AddRepeatedDatapoint(
      "Tlbmc-AllChassis-FetchState-End", absl::Now());

  if (!configs.ok()) {
    resp.SetToAbslStatus(configs.status());
    return;
  }

  milotic_tlbmc::Tracer::GetInstance().AddRepeatedDatapoint(
      "Tlbmc-AllChassis-Serialization-Begin", absl::Now());

  resp.SetKeyInJsonBody("/@odata.id", "/redfish/tlbmc/AllChassis");
  resp.SetKeyInJsonBody("/@odata.type", "#TlBMCAllChassis.TlBMCAllChassis");
  resp.SetKeyInJsonBody("/Name", "AllChassis");
  resp.SetKeyInJsonBody("/Description", "All Chassis on the machine");

  nlohmann::json::array_t members;
  std::vector<std::string> chassis_ids;
  std::sort(configs->begin(), configs->end());
  for (const auto& name : *configs) {
    absl::StatusOr<const TopologyConfigNode*> topo_node =
        store.GetFruTopology(name);
    if (!topo_node.ok()) {
      continue;
    }
    absl::StatusOr<const Fru*> fru =
        store.GetFru((*topo_node)->fru_info().fru_key());
    if (!fru.ok() ||
        (*fru)->attributes().resource_type() != RESOURCE_TYPE_BOARD) {
      continue;
    }

    nlohmann::json::object_t chassis_json;
    members.push_back(chassis_json);
    nlohmann::json::json_pointer chassis_pointer("/Members");
    chassis_pointer = chassis_pointer / (members.size() - 1);
    FillResponseWithFruData(chassis_pointer, *fru, *topo_node, resp);
  }
  resp.SetKeyInJsonBody("/Members@odata.count", members.size());
  milotic_tlbmc::Tracer::GetInstance().AddRepeatedDatapoint(
      "Tlbmc-AllChassis-Serialization-End", absl::Now());
}

}  // namespace

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

}  // namespace milotic_tlbmc::all_chassis
