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

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

#include "absl/functional/bind_front.h"
#include "absl/log/log.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "nlohmann/json.hpp"
#include "topology_config.pb.h"
#include "tlbmc/redfish/app.h"
#include "tlbmc/redfish/data/stable_id.h"
#include "stable_id.pb.h"
#include "tlbmc/redfish/request.h"
#include "tlbmc/redfish/response.h"
#include "tlbmc/redfish/url.h"
#include "fru.pb.h"
#include "resource.pb.h"
#include "tlbmc/store/store.h"

namespace milotic_tlbmc::cable {

void HandleCableCollection(const RedfishApp& app, const RedfishRequest& req,
                           RedfishResponse& resp) {
  resp.SetKeyInJsonBody("/@odata.id", "/redfish/v1/Cables");
  resp.SetKeyInJsonBody("/@odata.type", "#CableCollection.CableCollection");
  resp.SetKeyInJsonBody("/Name", "Cable Collection");

  const Store& store = *app.GetStore();
  absl::StatusOr<std::vector<std::string>> config_keys =
      store.GetAllConfigKeys();
  if (!config_keys.ok()) {
    resp.SetToAbslStatus(config_keys.status());
    return;
  }

  std::vector<std::string> cable_names;
  for (const std::string& name : *config_keys) {
    absl::StatusOr<std::string> fru_key = store.GetFruKeyByConfigKey(name);
    if (!fru_key.ok()) {
      continue;
    }
    absl::StatusOr<const Fru*> fru = store.GetFru(*fru_key);
    if (!fru.ok() ||
        (*fru)->attributes().resource_type() != RESOURCE_TYPE_CABLE) {
      continue;
    }
    cable_names.push_back(name);
  }
  std::sort(cable_names.begin(), cable_names.end());

  nlohmann::json::array_t members;
  for (const auto& name : cable_names) {
    nlohmann::json::object_t member;
    member["@odata.id"] = absl::StrCat("/redfish/v1/Cables/", name);
    members.push_back(std::move(member));
  }
  resp.SetKeyInJsonBody("/Members", members);
  resp.SetKeyInJsonBody("/Members@odata.count", members.size());
}

void HandleCable(const RedfishApp& app, const RedfishRequest& req,
                 RedfishResponse& resp, absl::string_view cable_id) {
  const Store& store = *app.GetStore();
  absl::StatusOr<std::string> fru_key = store.GetFruKeyByConfigKey(cable_id);
  if (!fru_key.ok()) {
    resp.SetToAbslStatus(fru_key.status());
    return;
  }
  absl::StatusOr<const Fru*> fru = store.GetFru(*fru_key);
  if (!fru.ok()) {
    resp.SetToAbslStatus(fru.status());
    return;
  }
  absl::StatusOr<const TopologyConfigNode*> topology_config_node =
      store.GetFruTopology(cable_id);
  if (!topology_config_node.ok()) {
    resp.SetToAbslStatus(topology_config_node.status());
    return;
  }

  FillResponseWithCableData(nlohmann::json::json_pointer(""), *fru,
                            *topology_config_node, resp);
}

void FillResponseWithCableData(
    const nlohmann::json::json_pointer& cable_ptr, const Fru* cable_fru_ptr,
    const TopologyConfigNode* topology_config_node_ptr, RedfishResponse& resp) {
  const std::string& cable_name = topology_config_node_ptr->name();

  if (cable_fru_ptr->attributes().status() != STATUS_READY) {
    resp.SetToNotReady(
        absl::StrFormat("Cable %s is not ready in tlBMC Store", cable_name));
    return;
  }
  resp.SetKeyInJsonBody(cable_ptr / "@odata.id",
                        CreateUrl({"redfish", "v1", "Cables", cable_name}));
  resp.SetKeyInJsonBody(cable_ptr / "@odata.type", "#Cable.v1_2_4.Cable");
  resp.SetKeyInJsonBody(cable_ptr / "Id", cable_name);
  resp.SetKeyInJsonBody(cable_ptr / "Name", cable_name);

  nlohmann::json::array_t downstream_chassis;
  for (const std::string& chassis_id :
       topology_config_node_ptr->children_chassis_ids()) {
    nlohmann::json::object_t downstream_chassis_obj;
    downstream_chassis_obj["@odata.id"] =
        CreateUrl({"redfish", "v1", "Chassis", chassis_id});
    downstream_chassis.emplace_back(std::move(downstream_chassis_obj));
  }
  resp.SetKeyInJsonBody(cable_ptr / "Links" / "DownstreamChassis",
                        downstream_chassis);
  resp.SetKeyInJsonBody(cable_ptr / "Links" / "DownstreamChassis@odata.count",
                        downstream_chassis.size());

  nlohmann::json::array_t upstream_chassis;
  for (const auto& chassis_id :
       topology_config_node_ptr->parent_chassis_ids()) {
    nlohmann::json::object_t upstream_chassis_obj;
    upstream_chassis_obj["@odata.id"] =
        CreateUrl({"redfish", "v1", "Chassis", chassis_id});
    upstream_chassis.emplace_back(std::move(upstream_chassis_obj));
  }
  resp.SetKeyInJsonBody(cable_ptr / "Links" / "UpstreamChassis",
                        upstream_chassis);
  resp.SetKeyInJsonBody(cable_ptr / "Links" / "UpstreamChassis@odata.count",
                        upstream_chassis.size());

  StableId stable_id = GetStableId(*topology_config_node_ptr);
  if (!stable_id.service_label().empty()) {
    resp.SetKeyInJsonBody(
        cable_ptr / "Location" / "PartLocation" / "ServiceLabel",
        stable_id.service_label());
  }
  if (!stable_id.part_location_context().empty() &&
      stable_id.part_location_context() != "phys") {
    resp.SetKeyInJsonBody(cable_ptr / "Location" / "PartLocationContext",
                          stable_id.part_location_context());
  }
  if (stable_id.has_location_type()) {
    absl::string_view location_type;
    switch (stable_id.location_type()) {
      case PART_LOCATION_TYPE_CONNECTOR:
        location_type = "Connector";
        break;
      case PART_LOCATION_TYPE_BACKPLANE:
      case PART_LOCATION_TYPE_BAY:
      case PART_LOCATION_TYPE_EMBEDDED:
      case PART_LOCATION_TYPE_SLOT:
      case PART_LOCATION_TYPE_SOCKET:
      default:
        LOG(WARNING) << "Unsupported location type for cable: "
                     << stable_id.location_type();
        break;
    }
    if (!location_type.empty()) {
      resp.SetKeyInJsonBody(
          cable_ptr / "Location" / "PartLocation" / "LocationType",
          location_type);
    }
  }

  resp.SetKeyInJsonBody(cable_ptr / "Status" / "Health", "OK");
  resp.SetKeyInJsonBody(cable_ptr / "Status" / "State", "Enabled");
}

void RegisterRoutes(RedfishApp& app) {
  TLBMC_ROUTE(app, "/redfish/v1/Cables/")
      .methods(boost::beast::http::verb::get)(
          absl::bind_front(HandleCableCollection, std::cref(app)));
  TLBMC_ROUTE(app, "/redfish/v1/Cables/<str>/")
      .methods(boost::beast::http::verb::get)(
          absl::bind_front(HandleCable, std::cref(app)));
}

}  // namespace milotic_tlbmc::cable
