#include "tlbmc/hal/shared_mem/metrics.h"

#include <sys/stat.h>

#include <algorithm>
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iterator>
#include <limits>
#include <string>
#include <string_view>
#include <utility>

#include "absl/container/btree_set.h"
#include "absl/strings/substitute.h"
#include "absl/time/time.h"
#include "nlohmann/json.hpp"
#include "pattern_to_entity_array.h"
#include "bmcweb_authorizer_singleton.h"

namespace milotic_tlbmc {

using ::milotic::authz::BmcWebAuthorizerSingleton;
using ::milotic::authz::pattern_entity_pair_array;

void TlbmcMetrics::UpdateMetricsRequestCount(bool is_tlbmc_request) {
  if (is_tlbmc_request) {
    total_tlbmc_request_count_.fetch_add(1, std::memory_order_relaxed);
  } else {
    total_gbmcweb_request_count_.fetch_add(1, std::memory_order_relaxed);
  }
}

void TlbmcMetrics::UpdateMetricsResponse(absl::Duration response_time,
                                         int status_code,
                                         std::string_view resource_url) {
  // Update response status code count.
  bool supported_status_code = std::binary_search(
      kSupportedStatusCodes.begin(), kSupportedStatusCodes.end(), status_code);
  if (supported_status_code) {
    response_status_code_count_[status_code].fetch_add(
        1, std::memory_order_relaxed);
  } else {
    response_status_code_count_[kMaxResponseStatusCode].fetch_add(
        1, std::memory_order_relaxed);
  }

  // Update response time histogram.
  int64_t bucket_index = response_time / kResponseTimeHistogramBucketTime;
  if (bucket_index >= kResponseTimeHistogramBucketCount) {
    bucket_index = 19;
  }
  response_time_histogram_[bucket_index].fetch_add(1,
                                                   std::memory_order_relaxed);

  size_t index =
      BmcWebAuthorizerSingleton::GetInstance().GetNodeIndexInPatternArray(
          resource_url);
  if (index != std::numeric_limits<std::size_t>::max()) {
    MetricsIntegerType response_time_ms =
        static_cast<MetricsIntegerType>(response_time / absl::Milliseconds(1));
    response_total_latency_ms_per_resource_[index].fetch_add(
        response_time_ms, std::memory_order_relaxed);
    total_response_count_per_resource_[index].fetch_add(
        1, std::memory_order_relaxed);
  }
}

nlohmann::json TlbmcMetrics::ToJson() const {
  nlohmann::json json;
  json["TotalTlbmcRequestCount"] = total_tlbmc_request_count_.load();
  json["TotalGbmcwebRequestCount"] = total_gbmcweb_request_count_.load();
  // Response status code count.
  nlohmann::json::array_t response_status_code_count_json;
  for (int code : kSupportedStatusCodes) {
    nlohmann::json response_status_code_pair;
    response_status_code_pair["ResponseStatusCode"] = std::to_string(code);
    response_status_code_pair["Count"] =
        response_status_code_count_[code].load();
    response_status_code_count_json.push_back(response_status_code_pair);
  }
  nlohmann::json response_status_code_pair;
  response_status_code_pair["ResponseStatusCode"] =
      std::to_string(kMaxResponseStatusCode);
  response_status_code_pair["Count"] =
      response_status_code_count_[kMaxResponseStatusCode].load();
  response_status_code_count_json.push_back(response_status_code_pair);
  json["ResponseStatusCodeCount"] = response_status_code_count_json;
  // Response time histogram.
  nlohmann::json::array_t response_time_histogram_json;
  for (int i = 0; i < kResponseTimeHistogramBucketCount; ++i) {
    nlohmann::json response_time_histogram_pair;
    std::string bucket_name;
    if (i != kResponseTimeHistogramBucketCount - 1) {
      bucket_name = absl::Substitute("$0ms", (i + 1) * 50 - 1);
    } else {
      bucket_name = "inf";
    }
    response_time_histogram_pair["ResponseTime"] = bucket_name;
    response_time_histogram_pair["Count"] = response_time_histogram_[i].load();
    response_time_histogram_json.push_back(response_time_histogram_pair);
  }
  json["ResponseTimeHistogram"] = response_time_histogram_json;
  // Top latency resources.
  // Find the top k resources with the highest average latency.
  absl::btree_set<std::pair<float, int>, std::greater<>> top_latency_resources;
  for (int i = 0; i < kResourceCount; ++i) {
    MetricsIntegerType total_latency_ms =
        response_total_latency_ms_per_resource_[i].load();
    MetricsIntegerType total_response_count =
        total_response_count_per_resource_[i].load();
    if (total_response_count > 0) {
      top_latency_resources.insert(
          {static_cast<float>(total_latency_ms) /
               static_cast<float>(total_response_count),
           i});
      if (top_latency_resources.size() > kTopLatencyResourcesCount) {
        top_latency_resources.erase(std::prev(top_latency_resources.end()));
      }
    }
  }
  // Insert the top k resources into the json.
  nlohmann::json::array_t top_latency_resources_json;
  for (const auto& [average_latency_ms, index] : top_latency_resources) {
    nlohmann::json resource_latency_pair;
    resource_latency_pair["Name"] =
        std::string(pattern_entity_pair_array[index].first);
    resource_latency_pair["Latency"] =
        absl::Substitute("$0ms", average_latency_ms);
    top_latency_resources_json.push_back(resource_latency_pair);
  }
  json["TopLatencyResources"] = top_latency_resources_json;
  return json;
}

}  // namespace milotic_tlbmc
