#include "tlbmc/redfish/routes/chassis.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 "nlohmann/json_fwd.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"
#include "google/protobuf/repeated_ptr_field.h"

namespace milotic_tlbmc::chassis {

namespace {

void HandleChassisCollection(const RedfishApp& app, const RedfishRequest& req,
                             RedfishResponse& resp) {
  resp.SetKeyInJsonBody("/@odata.id", "/redfish/v1/Chassis");
  resp.SetKeyInJsonBody("/@odata.type", "#ChassisCollection.ChassisCollection");
  resp.SetKeyInJsonBody("/Name", "Chassis Collection");

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

  resp.SetKeyInJsonBody("/Members@odata.count", config_names->size());
  nlohmann::json::array_t members;
  for (const auto& config : *config_names) {
    nlohmann::json::object_t member;
    member["@odata.id"] = CreateUrl({"redfish", "v1", "Chassis", config});
    members.push_back(std::move(member));
  }
  std::sort(members.begin(), members.end());
  resp.SetKeyInJsonBody("/Members", members);
}

void HandleChassis(const RedfishApp& app, const RedfishRequest& req,
                   RedfishResponse& resp, const std::string& chassis_id) {
  const Store& store = *app.GetStore();
  nlohmann::json::json_pointer chassis_pointer("");
  // Chassis id corresponds to the config name.
  absl::StatusOr<std::string> fru_key = store.GetFruKeyByConfigName(chassis_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(chassis_id);
  if (!topology_config_node.ok()) {
    resp.SetToAbslStatus(topology_config_node.status());
    return;
  }
  FillResponseWithFruData(chassis_pointer, *fru, *topology_config_node, resp);
}

inline std::string GetSystemId() { return "system"; }

nlohmann::json::array_t CreateChildResourceLinksArray(
    const ::google::protobuf::RepeatedPtrField<std::string>& child_resource_ids,
    ResourceType resource_type) {
  nlohmann::json::array_t child_resources;
  for (const auto& id : child_resource_ids) {
    nlohmann::json::object_t child_object;
    switch (resource_type) {
      case RESOURCE_TYPE_BOARD:
        child_object["@odata.id"] = CreateUrl({"redfish", "v1", "Chassis", id});
        break;
      case RESOURCE_TYPE_CABLE:
        child_object["@odata.id"] = CreateUrl({"redfish", "v1", "Cables", id});
        break;
      case RESOURCE_TYPE_PROCESSOR:
        child_object["@odata.id"] = CreateUrl(
            {"redfish", "v1", "Systems", GetSystemId(), "Processors", id});
        break;
      case RESOURCE_TYPE_STORAGE:
        child_object["@odata.id"] = CreateUrl(
            {"redfish", "v1", "Systems", GetSystemId(), "Storage", id});
        break;
      default:
        break;
    }
    child_resources.emplace_back(child_object);
  }
  return child_resources;
}
}  // namespace

void FillResponseWithFruData(
    const nlohmann::json::json_pointer& chassis_pointer, const Fru* fru_ptr,
    const TopologyConfigNode* topology_config_node_ptr, RedfishResponse& resp) {
  const std::string& chassis_id = topology_config_node_ptr->name();

  if (fru_ptr->attributes().status() != STATUS_READY) {
    resp.SetToNotReady(
        absl::StrFormat("Chassis %s is not ready in tlBMC Store", chassis_id));
    return;
  }
  resp.SetKeyInJsonBody(chassis_pointer / "@odata.id",
                        "/redfish/v1/Chassis/" + chassis_id);
  resp.SetKeyInJsonBody(chassis_pointer / "@odata.type",
                        "#Chassis.v1_17_0.Chassis");
  resp.SetKeyInJsonBody(
      chassis_pointer / "Assembly" / "@odata.id",
      CreateUrl({"redfish", "v1", "Chassis", chassis_id, "Assembly"}));
  resp.SetKeyInJsonBody(
      chassis_pointer / "Certificates" / "@odata.id",
      CreateUrl({"redfish", "v1", "Chassis", chassis_id, "Certificates"}));
  resp.SetKeyInJsonBody(
      chassis_pointer / "TrustedComponents" / "@odata.id",
      milotic_tlbmc::CreateUrl(
          {"redfish", "v1", "Chassis", chassis_id, "TrustedComponents"}));
  absl::string_view chassis_type;
  switch (fru_ptr->attributes().chassis_properties().chassis_type()) {
    case CHASSIS_TYPE_RACK_MOUNT:
      chassis_type = "RackMount";
      break;
    case CHASSIS_TYPE_MODULE:
      chassis_type = "Module";
      break;
    case CHASSIS_TYPE_STORAGE_ENCLOSURE:
      chassis_type = "StorageEnclosure";
      break;
    case CHASSIS_TYPE_COMPONENT:
      chassis_type = "Component";
      break;
    case CHASSIS_TYPE_STANDALONE:
      chassis_type = "StandAlone";
      break;
    default:
      break;
  }
  resp.SetKeyInJsonBody(chassis_pointer / "ChassisType", chassis_type);

  if (fru_ptr->attributes().chassis_properties().bmcnet()) {
    resp.SetKeyInJsonBody(
        chassis_pointer / "NetworkAdapters" / "@odata.id",
        milotic_tlbmc::CreateUrl(
            {"redfish", "v1", "Chassis", chassis_id, "NetworkAdapters"}));
  }

  // Support Chassis Reset Action only for Root Chassis.
  if (topology_config_node_ptr->location_context().devpath() == "/phys" ||
      topology_config_node_ptr->location_context().devpath() ==
          absl::StrCat(
              "/", topology_config_node_ptr->root_chassis_location_code())) {
    resp.SetKeyInJsonBody(
        chassis_pointer / "Actions" / "#Chassis.Reset" / "target",
        CreateUrl({"redfish", "v1", "Chassis", chassis_id, "Actions",
                   "Chassis.Reset"}));
    resp.SetKeyInJsonBody(
        chassis_pointer / "Actions" / "#Chassis.Reset" / "@Redfish.ActionInfo",
        CreateUrl({"redfish", "v1", "Chassis", chassis_id, "ResetActionInfo"}));
  }
  resp.SetKeyInJsonBody(
      chassis_pointer / "Drives" / "@odata.id",
      CreateUrl({"redfish", "v1", "Chassis", chassis_id, "Drives"}));
  resp.SetKeyInJsonBody(
      chassis_pointer / "Memory" / "@odata.id",
      CreateUrl({"redfish", "v1", "Systems", GetSystemId(), "Memory"}));
  resp.SetKeyInJsonBody(chassis_pointer / "Id", chassis_id);
  resp.SetKeyInJsonBody(chassis_pointer / "Name", chassis_id);
  resp.SetKeyInJsonBody(
      chassis_pointer / "Sensors" / "@odata.id",
      CreateUrl({"redfish", "v1", "Chassis", chassis_id, "Sensors"}));

  resp.SetKeyInJsonBody(
      chassis_pointer / "Thermal" / "@odata.id",
      CreateUrl({"redfish", "v1", "Chassis", chassis_id, "Thermal"}));
  resp.SetKeyInJsonBody(
      chassis_pointer / "Power" / "@odata.id",
      CreateUrl({"redfish", "v1", "Chassis", chassis_id, "Power"}));

  resp.SetKeyInJsonBody(
      chassis_pointer / "ThermalSubsystem" / "@odata.id",
      CreateUrl({"redfish", "v1", "Chassis", chassis_id, "ThermalSubsystem"}));
  resp.SetKeyInJsonBody(
      chassis_pointer / "PowerSubsystem" / "@odata.id",
      CreateUrl({"redfish", "v1", "Chassis", chassis_id, "PowerSubsystem"}));
  resp.SetKeyInJsonBody(chassis_pointer / "EnvironmentMetrics" / "@odata.id",
                        CreateUrl({"redfish", "v1", "Chassis", chassis_id,
                                   "EnvironmentMetrics"}));

  resp.SetKeyInJsonBody(chassis_pointer / "PowerState", "On");

  resp.SetKeyInJsonBody(chassis_pointer / "PCIeDevices" / "@odata.id",
                        "/redfish/v1/Systems/system/PCIeDevices");
  resp.SetKeyInJsonBody(
      chassis_pointer / "PCIeSlots" / "@odata.id",
      CreateUrl({"redfish", "v1", "Chassis", chassis_id, "PCIeSlots"}));

  if (fru_ptr->data().has_asset_info()) {
    const AssetInfo& asset_info = fru_ptr->data().asset_info();
    if (!asset_info.manufacturer().empty()) {
      resp.SetKeyInJsonBody(chassis_pointer / "Manufacturer",
                            asset_info.manufacturer());
    }
    if (!asset_info.product_name().empty()) {
      resp.SetKeyInJsonBody(chassis_pointer / "Model",
                            asset_info.product_name());
    }
    if (!asset_info.serial_number().empty()) {
      resp.SetKeyInJsonBody(chassis_pointer / "SerialNumber",
                            asset_info.serial_number());
    }
    if (!asset_info.part_number().empty()) {
      resp.SetKeyInJsonBody(chassis_pointer / "PartNumber",
                            asset_info.part_number());
    }
  }

  if (topology_config_node_ptr->has_location_context()) {
    StableId stable_id = GetStableId(*topology_config_node_ptr);

    if (!stable_id.service_label().empty()) {
      resp.SetKeyInJsonBody(
          chassis_pointer / "Location" / "PartLocation" / "ServiceLabel",
          stable_id.service_label());
      if (stable_id.has_location_type()) {
        absl::string_view location_type;
        switch (stable_id.location_type()) {
          case PART_LOCATION_TYPE_BACKPLANE:
            location_type = "Backplane";
            break;
          case PART_LOCATION_TYPE_BAY:
            location_type = "Bay";
            break;
          case PART_LOCATION_TYPE_EMBEDDED:
            location_type = "Embedded";
            break;
          case PART_LOCATION_TYPE_SLOT:
            location_type = "Slot";
            break;
          case PART_LOCATION_TYPE_SOCKET:
            location_type = "Socket";
            break;
          default:
            break;
        }
        if (!location_type.empty()) {
          resp.SetKeyInJsonBody(
              chassis_pointer / "Location" / "PartLocation" / "LocationType",
              location_type);
        }
      }
    }
    if (!stable_id.part_location_context().empty() &&
        stable_id.part_location_context() != "phys") {
      resp.SetKeyInJsonBody(
          chassis_pointer / "Location" / "PartLocationContext",
          stable_id.part_location_context());
    }
    if (stable_id.has_embedded_location_context()) {
      resp.SetKeyInJsonBody(chassis_pointer / "Location" / "Oem" / "Google" /
                                "EmbeddedLocationContext",
                            stable_id.embedded_location_context());
    }
    // Populate special devpath field for embedded chassis.
    if (stable_id.location_type() == PART_LOCATION_TYPE_EMBEDDED) {
      resp.SetKeyInJsonBody(
          chassis_pointer / "Location" / "Oem" / "Google" / "Devpath",
          stable_id.machine_local_devpath());
    }
  }

  nlohmann::json::array_t child_chassis = CreateChildResourceLinksArray(
      topology_config_node_ptr->children_chassis_ids(), RESOURCE_TYPE_BOARD);
  if (!child_chassis.empty()) {
    resp.SetKeyInJsonBody(chassis_pointer / "Links" / "Contains",
                          child_chassis);
    resp.SetKeyInJsonBody(chassis_pointer / "Links" / "Contains@odata.count",
                          child_chassis.size());
  }

  nlohmann::json::array_t child_cables = CreateChildResourceLinksArray(
      topology_config_node_ptr->children_cable_ids(), RESOURCE_TYPE_CABLE);
  if (!child_cables.empty()) {
    resp.SetKeyInJsonBody(chassis_pointer / "Links" / "Cables", child_cables);
    resp.SetKeyInJsonBody(chassis_pointer / "Links" / "Cables@odata.count",
                          child_cables.size());
  }

  nlohmann::json::array_t child_processors = CreateChildResourceLinksArray(
      topology_config_node_ptr->children_processor_ids(),
      RESOURCE_TYPE_PROCESSOR);
  if (!child_processors.empty()) {
    resp.SetKeyInJsonBody(chassis_pointer / "Links" / "Processors",
                          child_processors);
    resp.SetKeyInJsonBody(chassis_pointer / "Links" / "Processors@odata.count",
                          child_processors.size());
  }

  nlohmann::json::array_t child_storages = CreateChildResourceLinksArray(
      topology_config_node_ptr->children_storage_ids(), RESOURCE_TYPE_STORAGE);
  if (!child_storages.empty()) {
    resp.SetKeyInJsonBody(chassis_pointer / "Links" / "Storage",
                          child_storages);
    resp.SetKeyInJsonBody(chassis_pointer / "Links" / "Storage@odata.count",
                          child_storages.size());
  }

  if (topology_config_node_ptr->has_parent_resource_id()) {
    resp.SetKeyInJsonBody(
        chassis_pointer / "Links" / "ContainedBy" / "@odata.id",
        CreateUrl({"redfish", "v1", "Chassis",
                   topology_config_node_ptr->parent_resource_id()}));
  }

  nlohmann::json::array_t managed_by;
  nlohmann::json::object_t manager;
  manager["@odata.id"] = "/redfish/v1/Managers/bmc";
  managed_by.emplace_back(manager);
  resp.SetKeyInJsonBody(chassis_pointer / "Links" / "ManagedBy", managed_by);

  // TODO(davtang): Add support for multihost systems
  nlohmann::json::array_t systems;
  nlohmann::json::object_t system;
  system["@odata.id"] = "/redfish/v1/Systems/system";
  systems.emplace_back(system);
  resp.SetKeyInJsonBody(chassis_pointer / "Links" / "ComputerSystems", systems);

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

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

}  // namespace milotic_tlbmc::chassis
