#include "tlbmc/redfish/data/stable_id.h"

#include <string>
#include <vector>

#include "absl/log/log.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "topology_config.pb.h"
#include "stable_id.pb.h"
#include "resource.pb.h"

namespace milotic_tlbmc {

std::string GetNodeLocalDevpath(const std::string& devpath,
                                const std::string& root_chassis_location_code) {
  // If the root chassis location code is empty, then the devpath is already
  // machine local.
  if (root_chassis_location_code.empty()) {
    return devpath;
  }

  // The root chassis location code should ALWAYS be the prefix of the devpath.
  // If it is not, then we have an error and return the empty string.
  if (!absl::StrContains(devpath,
                         absl::StrCat("/", root_chassis_location_code))) {
    LOG(ERROR) << "Root chassis location code " << root_chassis_location_code
               << " is not a prefix of the devpath " << devpath;
    return "";
  }

  // If the beginning is not /phys, then replace the beginning devpath part with
  // /phys.
  return absl::StrCat("/phys",
                      // +1 here to include the first "/" in the devpath.
                      devpath.substr(root_chassis_location_code.size() + 1));
}

StableId GetStableId(const TopologyConfigNode& topology_config_node) {
  StableId stable_id;

  const LocationContext& location_context =
      topology_config_node.location_context();
  std::string devpath = location_context.devpath();

  stable_id.set_machine_local_devpath(GetNodeLocalDevpath(
      devpath, topology_config_node.root_chassis_location_code()));

  // Remove /phys from the devpath.
  if (absl::StartsWith(devpath, "/phys")) {
    devpath = devpath.substr(5);
  }

  // Find and remove the port label from the devpath.
  std::string embedded_port_label;
  auto find_device = devpath.find(":device:");
  if (find_device != std::string::npos) {
    embedded_port_label = devpath.substr(find_device + 8);
    devpath = devpath.substr(0, find_device);
  }

  std::vector<std::string> devpath_parts =
      absl::StrSplit(devpath, '/', absl::SkipEmpty());
  if (devpath_parts.empty() && embedded_port_label.empty()) {
    return stable_id;
  }

  if (!embedded_port_label.empty()) {
    stable_id.set_service_label(embedded_port_label);
    stable_id.set_part_location_context(
        absl::StrJoin(devpath_parts.begin(), devpath_parts.end(), "/"));
  } else {
    stable_id.set_service_label(devpath_parts.back());
    stable_id.set_part_location_context(
        absl::StrJoin(devpath_parts.begin(), devpath_parts.end() - 1, "/"));
  }

  std::string embedded_location_context;
  for (const auto& logical_identifier :
       location_context.logical_identifiers()) {
    absl::StrAppend(&embedded_location_context,
                    embedded_location_context.empty() ? "" : "/",
                    logical_identifier);
  }
  if (!embedded_location_context.empty()) {
    stable_id.set_embedded_location_context(embedded_location_context);
  }

  if (location_context.has_location_type()) {
    stable_id.set_location_type(location_context.location_type());
  }

  return stable_id;
}
}  // namespace milotic_tlbmc
