#pragma once

#include "managed_store_clock.hpp"

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

#include <map>
#include <string>
#include <string_view>
#include <vector>

// 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
