#include "tlbmc/redfish/query_parameters.h"

#include <cstddef>
#include <string>
#include <vector>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/match.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
#include "boost/url/params_view.hpp"
#include <nlohmann/json.hpp>

namespace milotic_tlbmc {

std::string ExpandTypeToUrlParam(ExpandType expand_type) {
  switch (expand_type) {
    case ExpandType::kNoLinks:
      return ".";
    case ExpandType::kLinksOnly:
      return "~";
    case ExpandType::kAll:
      return "*";
    default:
      return "";
  }
}

absl::StatusOr<QueryParameters> QueryParameters::Create(
    boost::urls::params_view request_query_parameters) {
  QueryParameters query_parameters;
  if (request_query_parameters.empty()) {
    return query_parameters;
  }

  for (const boost::urls::params_view::value_type it :
       request_query_parameters) {
    if (it.key == "$expand") {
      // We have to parse the expand type and levels if applicable.
      // Examples: $expand=. or $expand=.($levels=2)

      // We support the following
      // expand=. (Expand with no links)
      // expand=~ (Expand only links)
      // expand=* (Expand all)
      absl::string_view param_value = it.value;
      if (absl::StartsWith(param_value, ".")) {
        query_parameters.SetExpandType(ExpandType::kNoLinks);
        param_value = absl::StripPrefix(param_value, ".");
      } else if (absl::StartsWith(param_value, "~")) {
        query_parameters.SetExpandType(ExpandType::kLinksOnly);
        param_value = absl::StripPrefix(param_value, "~");
      } else if (absl::StartsWith(param_value, "*")) {
        query_parameters.SetExpandType(ExpandType::kAll);
        param_value = absl::StripPrefix(param_value, "*");
      }

      // Expand level is defaulted to 1.
      query_parameters.SetExpandLevel(1);

      if (param_value.empty()) {
        continue;
      }

      // Get levels if exists
      if (!absl::StartsWith(param_value, "($levels=") ||
          !absl::EndsWith(param_value, ")")) {
        return absl::InvalidArgumentError(
            absl::StrFormat("Invalid Expand Syntax. Got: %s", param_value));
      }
      param_value = absl::StripPrefix(param_value, "($levels=");
      param_value = absl::StripSuffix(param_value, ")");
      int expand_level = 0;
      if (!absl::SimpleAtoi(param_value, &expand_level)) {
        return absl::InvalidArgumentError(absl::StrFormat(
            "Expand Level was not a number. Got: %s", param_value));
      }
      if (expand_level < 0) {
        return absl::InvalidArgumentError(absl::StrFormat(
            "Expand Level was negative. Got: %d", expand_level));
      }
      constexpr int kMaxExpandLevel = 6;
      if (expand_level > kMaxExpandLevel) {
        return absl::InvalidArgumentError(absl::StrFormat(
            "Expand Level exceeds threshold limits (%d). Got: %d",
            kMaxExpandLevel, expand_level));
      }
      query_parameters.SetExpandLevel(expand_level);
    } else if (it.key == "$top") {
      int top = 0;
      if (!absl::SimpleAtoi(it.value, &top) || top < 0) {
        return absl::InvalidArgumentError(
            absl::StrFormat("Invalid $top value. Got: %s", it.value));
      }
      query_parameters.SetTop(top);
    } else if (it.key == "$filter") {
      query_parameters.SetFilter(it.value);
    } else {
      return absl::InvalidArgumentError(
          absl::StrFormat("Unsupported query parameter: %s", it.key));
    }
  }

  return query_parameters;
}

namespace {

void GetUnexpandedUrlsHelper(const nlohmann::json& resp_json,
                             const nlohmann::json::json_pointer& cur_pointer,
                             ExpandType expand_type, bool in_links,
                             std::vector<ExpandNode>& unexpanded_urls) {
  if (resp_json.is_primitive()) {
    return;
  }
  if (resp_json.is_array()) {
    for (size_t i = 0; i < resp_json.size(); ++i) {
      GetUnexpandedUrlsHelper(resp_json[i], cur_pointer / i, expand_type,
                              in_links, unexpanded_urls);
    }
    return;
  }

  if (resp_json.is_object()) {
    // Unexpanded URLs are objects with only an @odata.id
    if (resp_json.size() == 1 && resp_json.contains("@odata.id")) {
      unexpanded_urls.push_back(ExpandNode{.json_pointer = cur_pointer,
                                           .url = resp_json["@odata.id"]});
      return;
    }

    // Otherwise recurse on object values
    for (const auto& [key, value] : resp_json.items()) {
      bool local_in_links = in_links;
      if (!local_in_links) {
        // Check if this is a links node
        local_in_links = key == "Links";
      }
      // Only traverse the parts of the tree the user asked for
      // Per section 7.3 of the redfish specification
      if (local_in_links && expand_type == ExpandType::kNoLinks) {
        continue;
      }
      if (!local_in_links && expand_type == ExpandType::kLinksOnly) {
        continue;
      }

      GetUnexpandedUrlsHelper(value, cur_pointer / key, expand_type,
                              local_in_links, unexpanded_urls);
    }
  }
}

}  // namespace

std::vector<ExpandNode> GetUnexpandedUrls(const nlohmann::json& resp,
                                          ExpandType expand_type) {
  std::vector<ExpandNode> unexpanded_urls;
  GetUnexpandedUrlsHelper(resp, nlohmann::json::json_pointer(""), expand_type,
                          false, unexpanded_urls);
  return unexpanded_urls;
}

}  // namespace milotic_tlbmc
