#pragma once
#include <drogon/utils/monitoring/Metric.h>
#include <string_view>
#include <atomic>
namespace drogon
{
namespace monitoring
{
class Gauge : public Metric
{
  public:
    Gauge(const std::string &name,
          const std::vector<std::string> &labelNames,
          const std::vector<std::string> &labelValues) noexcept(false)
        : Metric(name, labelNames, labelValues)
    {
    }
    std::vector<Sample> collect() const override
    {
        Sample s;
        std::lock_guard<std::mutex> lock(mutex_);
        s.name = name_;
        s.value = value_;
        s.timestamp = timestamp_;
        return {s};
    }
    void increment()
    {
        std::lock_guard<std::mutex> lock(mutex_);
        value_ += 1;
    }
    void decrement()
    {
        std::lock_guard<std::mutex> lock(mutex_);
        value_ -= 1;
    }
    void decrement(double value)
    {
        std::lock_guard<std::mutex> lock(mutex_);
        value_ -= value;
    }
    void increment(double value)
    {
        std::lock_guard<std::mutex> lock(mutex_);
        value_ += value;
    }
    void reset()
    {
        std::lock_guard<std::mutex> lock(mutex_);
        value_ = 0;
    }
    void set(double value)
    {
        std::lock_guard<std::mutex> lock(mutex_);
        value_ = value;
    }
    static std::string_view type()
    {
        return "gauge";
    }
    void setToCurrentTime()
    {
        std::lock_guard<std::mutex> lock(mutex_);
        timestamp_ = trantor::Date::now();
    }
  private:
    mutable std::mutex mutex_;
    double value_{0};
    trantor::Date timestamp_{0};
};
}  
}  