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

#include <functional>
#include <utility>

#include "google/protobuf/timestamp.pb.h"
#include "absl/functional/bind_front.h"
#include "absl/strings/string_view.h"
#include "nlohmann/json.hpp"
#include "tlbmc/redfish/app.h"
#include "tlbmc/redfish/request.h"
#include "tlbmc/redfish/response.h"
#include "resource.pb.h"
#include "software_metrics.pb.h"
#include "tlbmc/store/store.h"

namespace milotic_tlbmc::metric {

static void HandleMetricSocketStats(const RedfishApp& app,
                                    const RedfishRequest& req,
                                    RedfishResponse& resp) {
  const Store& store = *app.GetStore();
  SocketStatStates metrics = store.GetMetricSocketStatValues();
  nlohmann::json::json_pointer metric_pointer("");
  resp.SetKeyInJsonBody(metric_pointer / "Port", nlohmann::json::object());
  resp.SetKeyInJsonBody(metric_pointer / "Timestamp",
                        metrics.timestamp().seconds());
  for (const auto& [port, state_data] : metrics.states()) {
    nlohmann::json port_data = nlohmann::json::object();

    port_data["LISTENING"] = state_data.listen();
    port_data["SYN_SENT"] = state_data.syn_sent();
    port_data["SYN_RECEIVED"] = state_data.syn_received();
    port_data["ESTABLISHED"] = state_data.established();
    port_data["FIN_WAIT_ONE"] = state_data.fin_wait_one();
    port_data["FIN_WAIT_TWO"] = state_data.fin_wait_two();
    port_data["CLOSE_WAIT"] = state_data.close_wait();
    port_data["CLOSING"] = state_data.closing();
    port_data["LAST_ACK"] = state_data.last_ack();
    port_data["TIME_WAIT"] = state_data.time_wait();
    port_data["CLOSED"] = state_data.closed();
    resp.SetKeyInJsonBody(metric_pointer / "Port" / port, port_data);
  }
}

static void HandleMetricNfStats(const RedfishApp& app,
                                const RedfishRequest& req,
                                RedfishResponse& resp) {
  const Store& store = *app.GetStore();
  NetFilterStates metrics = store.GetMetricNetFilterValues();
  nlohmann::json::json_pointer metric_pointer("");
  resp.SetKeyInJsonBody(metric_pointer / "Port", nlohmann::json::object());
  resp.SetKeyInJsonBody(metric_pointer / "Timestamp",
                        metrics.timestamp().seconds());
  for (const NetFilterState& state : metrics.states()) {
    nlohmann::json port_data = nlohmann::json::object();
    port_data["Connections"] = state.num_connections();
    resp.SetKeyInJsonBody(metric_pointer / "Port" / state.port(), port_data);
  }
}

void RegisterRoutes(RedfishApp& app) {
  TLBMC_ROUTE(app,
              "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/"
              "BmcSocketMetrics/")
      .methods(boost::beast::http::verb::get)(
          absl::bind_front(HandleMetricSocketStats, std::cref(app)));
  TLBMC_ROUTE(
      app,
      "/redfish/v1/Managers/bmc/ManagerDiagnosticData/Oem/Google/BmcNfMetrics/")
      .methods(boost::beast::http::verb::get)(
          absl::bind_front(HandleMetricNfStats, std::cref(app)));
}

}  // namespace milotic_tlbmc::metric
