#pragma once

#include <cstdint>
#include <string>
#include <tuple>
#include <vector>

namespace prometheus {

  // структура, в которую копируются значения метрик перед их сериализацией
  
  struct ClientMetric {

    // Label

    struct Label {

      std::string name;
      std::string value;

      Label(const std::string name_, const std::string value_) : name(name_), value(value_) {}

      bool operator<(const Label& rhs) const {
        return std::tie(name, value) < std::tie(rhs.name, rhs.value);
      }

      bool operator==(const Label& rhs) const {
        return std::tie(name, value) == std::tie(rhs.name, rhs.value);
      }

    };

    std::vector<Label> label;

    // Counter

    struct Counter {
      double value = 0.0;
    };

    Counter counter;

    // Gauge

    struct Gauge {
      double value = 0.0;
    };

    Gauge gauge;

    // Summary

    struct Quantile {
      double quantile = 0.0;
      double value    = 0.0;
    };

    struct Summary {
      std::uint64_t         sample_count = 0;
      double                sample_sum   = 0.0;
      std::vector<Quantile> quantile;
    };

    Summary summary;

    // Histogram

    struct Bucket {
      std::uint64_t cumulative_count = 0;
      double        upper_bound      = 0.0;
    };

    struct Histogram {
      std::uint64_t       sample_count = 0;
      double              sample_sum   = 0.0;
      std::vector<Bucket> bucket;
    };

    Histogram histogram;

    // Untyped

    struct Untyped {
      double value = 0;
    };

    Untyped untyped;

    // Timestamp

    std::int64_t timestamp_ms = 0;

  };

}  // namespace prometheus
