#ifndef THIRD_PARTY_GBMCWEB_INCLUDE_REQUEST_STATS_H_
#define THIRD_PARTY_GBMCWEB_INCLUDE_REQUEST_STATS_H_

#include <chrono>  // NOLINT
#include <cstdint>
#include <map>
#include <string>

#include "boost/beast/http/verb.hpp"  // NOLINT
#include "boost/url/url_view.hpp"  // NOLINT
#include <nlohmann/json.hpp>
#include "managed_store_clock.hpp"

// TODO:: probably need a new namespace? even though there is no good reason for
// it
// TODO:: probably will just rename to bmcweb
namespace managedStore {

struct RdeRequestStats {
  nlohmann::json toJson() const {
    nlohmann::json obj;
    obj["totalReqs"] = this->totalReqs;
    obj["totalDbusErrors"] = this->totalDbusErrors;
    obj["totalSkips"] = this->totalSkips;
    obj["totalRateLimitToggles"] = this->totalRateLimitToggles;
    obj["CurrentRdeDbusErrorCount"] = this->rdeDbusErrorCount;
    obj["CurrentRdeRequestSkips"] = this->rdeRequestSkips;
    return obj;
  }

  void clear() {
    this->totalReqs = 0;
    this->totalDbusErrors = 0;
    this->totalSkips = 0;
    this->totalRateLimitToggles = 0;
  }

  /** Total number of Rde Requests */
  int totalReqs = 0;
  /** Total number if dbus error in Rde Requests */
  int totalDbusErrors = 0;
  /** Total number Rde Requests skipped because of Rate Limit */
  int totalSkips = 0;
  /** Total number times Rde Requests Rate Limiter enabled */
  int totalRateLimitToggles = 0;

  // This is used to enable the rate limit the number of requests that can
  // be sent to the RDEd.
  /** Current Dbus error count*/
  int rdeDbusErrorCount = 0;

  // This keeps track number of skipped RDEd requests before turning off
  // rate limiting
  /** Current RDE Requests skip count*/
  int rdeRequestSkips = 0;
};

/** stats context captured by each request handler in the bmcweb */
class RequestStatsContext {
 public:
  explicit RequestStatsContext(const std::string& queryURLKey,
                               const std::chrono::steady_clock::time_point&
                                   now = managedStore::clockNow());
  virtual ~RequestStatsContext();
  RequestStatsContext(const RequestStatsContext&) = default;
  RequestStatsContext& operator=(const RequestStatsContext&) = default;
  RequestStatsContext(RequestStatsContext&&) = default;
  RequestStatsContext& operator=(RequestStatsContext&&) = default;

  nlohmann::json toJson() const;
  std::string getQueryURLKey() const;
  std::chrono::steady_clock::time_point getTimepointStart() const;
  void setOK(bool ok);
  bool ok() const;
  constexpr static const char kSep = '|';
  void updateRdeReqs();
  void updateRdeDbusErrors();
  void updateRdeSkips();
  void updateRdeRateLimitToggles();
  int getRdeReqs() const;
  int getRdeDbusErrors() const;
  int getRdeSkips() const;
  int getRdeRateLimitToggles() const;
  /** compose a key for the histogram bucket to agg the stats */
  static std::string queryURLKeyFor(const boost::beast::http::verb& method,
                                    const boost::urls::url_view& qURL);

 protected:
  std::string queryURLKey;
  bool isOK = false;
  std::chrono::steady_clock::time_point timepointStart;
  /** Rde Request Stats */
  RdeRequestStats rdeStats;
};

/** Stats collected by the RequestStatsStore */
struct RequestStats {
  nlohmann::json toJson() const {
    nlohmann::json obj;
    obj["countOK"] = this->countOK;
    obj["countError"] = this->countError;
    obj["latencyHistogram"] = nlohmann::json::array();
    for (const auto& histogramBucket : this->latencyHistogramMilliseconds) {
      nlohmann::json bucketJson;
      bucketJson["milliseconds"] = histogramBucket.first;
      bucketJson["count"] = histogramBucket.second;
      obj["latencyHistogram"].push_back(bucketJson);
    }
    return obj;
  }

  /** num of ok (200)*/
  int countOK = 0;
  /** num of errors (none 200)*/
  int countError = 0;

  /** sparse histogra buckets */
  std::map<int64_t, int64_t> latencyHistogramMilliseconds;
};

/** Static config for RequestStatsStore */
struct RequestStatsStoreConfig {
  nlohmann::json toJson() const;

  bool enable = true;
  /** config to enable rde rate limiting*/
  bool enableRdeRateLimit = false;
  /** Number of consecutive dbus error to trigger RDE Request Rate Limiting*/
  int rdeDbusErrorThreshold = 10;
  /** When rate limiting enabled, the number of RDE requests skipped
      before disabling disabling rate limit */
  int rdeMaxSkips = 30;
};

/** global store to track and managed aggregated stats */
class RequestStatsStore {
 public:
  static void initialize(const RequestStatsStoreConfig& config);
  /** singleton instance */
  static RequestStatsStore& instance();

  /** check if the store is enabled */
  static bool isEnabled() { return instance().getConfig().enable; }

  /** check if the rde rate limiting is enabled */
  static bool isRdeRateLimitEnabled() {
    return instance().getConfig().enableRdeRateLimit;
  }
  static int rdeErrorThreshold() {
    return instance().getConfig().rdeDbusErrorThreshold;
  }
  static int rdeMaxSkips() { return instance().getConfig().rdeMaxSkips; }
  /** log request stats */
  void logRequestStats(std::chrono::steady_clock::time_point now,
                       const RequestStatsContext& requestStatsContext);
  /** log Rde request stats */
  void logRdeRequestStats(const RequestStatsContext& requestStatsContext);

  /** reset all the stats */
  void clear();

  /** export JSON */
  nlohmann::json toJson() const;

  // Current RDE counters to enable/disable rate limiting
  void updateCurrentRdeDbusErrors();
  int getCurrentRdeDbusErrors() const;
  void setCurrentRdeDbusErrors(int errCount);

  void updateCurrentRdeRequestSkips();
  int getCurrentRdeRequestSkips() const;
  void setCurrentRdeRequestSkips(int skipCount);

  // used only for testing:
  explicit RequestStatsStore(const RequestStatsStoreConfig& config);
  virtual ~RequestStatsStore();
  RequestStatsStore(const RequestStatsStore&) = default;
  RequestStatsStore& operator=(const RequestStatsStore&) = default;
  RequestStatsStore(RequestStatsStore&&) = default;
  RequestStatsStore& operator=(RequestStatsStore&&) = default;

  /** read only stats */
  const std::map<std::string, RequestStats>& queryStats() const {
    return this->requestURLStats;
  }

  /** read only config */
  const RequestStatsStoreConfig& getConfig() const { return this->config; }

 protected:
  /** store config */
  RequestStatsStoreConfig config;
  /** redfish URL -> RequestStats */
  std::map<std::string, RequestStats> requestURLStats;
  /** Rde Request Stats */
  RdeRequestStats rdeStats;
};

}  // namespace managedStore

#endif  // THIRD_PARTY_GBMCWEB_INCLUDE_REQUEST_STATS_H_
