// Copyright 2013 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This is copied and lightly edited from
// github.com/prometheus/client_model/io/prometheus/client/metrics.proto
// and finally converted to proto3 syntax to make it usable for the
// gogo-protobuf approach taken within prometheus/prometheus.

syntax = "proto3";

package io.prometheus.client;
option go_package = "io_prometheus_client";

import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";

message LabelPair {
  string name  = 1;
  string value = 2;
}

enum MetricType {
  // COUNTER must use the Metric field "counter".
  COUNTER = 0;
  // GAUGE must use the Metric field "gauge".
  GAUGE = 1;
  // SUMMARY must use the Metric field "summary".
  SUMMARY = 2;
  // UNTYPED must use the Metric field "untyped".
  UNTYPED = 3;
  // HISTOGRAM must use the Metric field "histogram".
  HISTOGRAM = 4;
  // GAUGE_HISTOGRAM must use the Metric field "histogram".
  GAUGE_HISTOGRAM = 5;
}

message Gauge {
  double value = 1;
}

message Counter {
  double   value    = 1;
  Exemplar exemplar = 2;

  google.protobuf.Timestamp  created_timestamp = 3;
}

message Quantile {
  double quantile = 1;
  double value    = 2;
}

message Summary {
  uint64            sample_count = 1;
  double            sample_sum   = 2;
  repeated Quantile quantile     = 3 [(gogoproto.nullable) = false];

  google.protobuf.Timestamp  created_timestamp = 4;
}

message Untyped {
  double value = 1;
}

message Histogram {
  uint64 sample_count       = 1;
  double sample_count_float = 4; // Overrides sample_count if > 0.
  double sample_sum         = 2;
  // Buckets for the classic histogram.
  repeated Bucket bucket = 3 [(gogoproto.nullable) = false]; // Ordered in increasing order of upper_bound, +Inf bucket is optional.

  google.protobuf.Timestamp created_timestamp = 15;

  // Everything below here is for native histograms (also known as sparse histograms).
  // Native histograms are an experimental feature without stability guarantees.

  // schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.
  // They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and
  // then each power of two is divided into 2^n logarithmic buckets.
  // Or in other words, each bucket boundary is the previous boundary times 2^(2^-n).
  // In the future, more bucket schemas may be added using numbers < -4 or > 8.
  sint32 schema           = 5;
  double zero_threshold   = 6; // Breadth of the zero bucket.
  uint64 zero_count       = 7; // Count in zero bucket.
  double zero_count_float = 8; // Overrides sb_zero_count if > 0.

  // Negative buckets for the native histogram.
  repeated BucketSpan negative_span = 9 [(gogoproto.nullable) = false];
  // Use either "negative_delta" or "negative_count", the former for
  // regular histograms with integer counts, the latter for float
  // histograms.
  repeated sint64 negative_delta = 10; // Count delta of each bucket compared to previous one (or to zero for 1st bucket).
  repeated double negative_count = 11; // Absolute count of each bucket.

  // Positive buckets for the native histogram.
  // Use a no-op span (offset 0, length 0) for a native histogram without any
  // observations yet and with a zero_threshold of 0. Otherwise, it would be
  // indistinguishable from a classic histogram.
  repeated BucketSpan positive_span = 12 [(gogoproto.nullable) = false];
  // Use either "positive_delta" or "positive_count", the former for
  // regular histograms with integer counts, the latter for float
  // histograms.
  repeated sint64 positive_delta = 13; // Count delta of each bucket compared to previous one (or to zero for 1st bucket).
  repeated double positive_count = 14; // Absolute count of each bucket.
}

message Bucket {
  uint64   cumulative_count       = 1; // Cumulative in increasing order.
  double   cumulative_count_float = 4; // Overrides cumulative_count if > 0.
  double   upper_bound            = 2; // Inclusive.
  Exemplar exemplar               = 3;
}

// A BucketSpan defines a number of consecutive buckets in a native
// histogram with their offset. Logically, it would be more
// straightforward to include the bucket counts in the Span. However,
// the protobuf representation is more compact in the way the data is
// structured here (with all the buckets in a single array separate
// from the Spans).
message BucketSpan {
  sint32 offset = 1; // Gap to previous span, or starting point for 1st span (which can be negative).
  uint32 length = 2; // Length of consecutive buckets.
}

message Exemplar {
  repeated LabelPair        label     = 1 [(gogoproto.nullable) = false];
  double                    value     = 2;
  google.protobuf.Timestamp timestamp = 3; // OpenMetrics-style.
}

message Metric {
  repeated LabelPair label        = 1 [(gogoproto.nullable) = false];
  Gauge              gauge        = 2;
  Counter            counter      = 3;
  Summary            summary      = 4;
  Untyped            untyped      = 5;
  Histogram          histogram    = 7;
  int64              timestamp_ms = 6;
}

message MetricFamily {
  string          name   = 1;
  string          help   = 2;
  MetricType      type   = 3;
  repeated Metric metric = 4 [(gogoproto.nullable) = false];
  string          unit   = 5;
}
