// Nightlight PromQL Query API
//
// This API provides PromQL-compatible query endpoints for instant and range queries.
// The interface is designed to be compatible with Prometheus HTTP API v1 query semantics.

syntax = "proto3";

package nightlight;

// MetricQuery service provides PromQL query execution.
service MetricQuery {
  // Execute an instant query (single point in time)
  rpc InstantQuery(InstantQueryRequest) returns (QueryResponse);

  // Execute a range query (time range with step resolution)
  rpc RangeQuery(RangeQueryRequest) returns (QueryResponse);

  // Execute a series metadata query (find matching series)
  rpc SeriesQuery(SeriesQueryRequest) returns (SeriesQueryResponse);

  // Execute a label values query (find unique label values)
  rpc LabelValuesQuery(LabelValuesRequest) returns (LabelValuesResponse);
}

// InstantQueryRequest evaluates a PromQL expression at a single point in time.
message InstantQueryRequest {
  // PromQL expression to evaluate (e.g., "http_requests_total{job='api'}")
  string query = 1;

  // Evaluation timestamp in milliseconds since Unix epoch
  // If 0 or omitted, uses current time
  int64 time = 2;

  // Query timeout in milliseconds (optional)
  // If 0 or omitted, uses server default
  int64 timeout = 3;
}

// RangeQueryRequest evaluates a PromQL expression over a time range.
message RangeQueryRequest {
  // PromQL expression to evaluate
  string query = 1;

  // Range start time in milliseconds since Unix epoch
  int64 start = 2;

  // Range end time in milliseconds since Unix epoch
  int64 end = 3;

  // Resolution step in milliseconds
  // Determines the granularity of returned data points
  int64 step = 4;

  // Query timeout in milliseconds (optional)
  int64 timeout = 5;
}

// SeriesQueryRequest finds time series matching label matchers.
message SeriesQueryRequest {
  // Label matchers (e.g., ["__name__=http_requests_total", "job=api"])
  repeated string match = 1;

  // Time range start (optional, for filtering series by time)
  int64 start = 2;

  // Time range end (optional)
  int64 end = 3;
}

// LabelValuesRequest retrieves unique values for a label name.
message LabelValuesRequest {
  // Label name to query (e.g., "job", "instance")
  string label_name = 1;

  // Optional label matchers to filter series
  repeated string match = 2;

  // Time range start (optional)
  int64 start = 3;

  // Time range end (optional)
  int64 end = 4;
}

// QueryResponse is the unified response for instant and range queries.
message QueryResponse {
  // Status: "success" or "error"
  string status = 1;

  // Query result data (populated on success)
  QueryData data = 2;

  // Error message (populated on error)
  string error = 3;

  // Error type (e.g., "timeout", "bad_data", populated on error)
  string error_type = 4;

  // Warnings (non-fatal issues encountered during query execution)
  repeated string warnings = 5;
}

// QueryData contains the actual query results.
message QueryData {
  // Result type: "matrix" (range query), "vector" (instant query), "scalar", "string"
  string result_type = 1;

  // Query results (time series with values)
  repeated QueryResult result = 2;
}

// QueryResult represents a single time series result.
message QueryResult {
  // Metric labels (key-value pairs)
  // For instant queries: includes all series labels
  // For range queries: includes all series labels
  map<string, string> metric = 1;

  // Values for range queries (array of [timestamp, value] pairs)
  repeated SamplePair values = 2;

  // Single value for instant queries [timestamp, value]
  SamplePair value = 3;
}

// SamplePair is a [timestamp, value] tuple.
message SamplePair {
  // Timestamp in milliseconds since Unix epoch
  int64 timestamp = 1;

  // Sample value
  double value = 2;
}

// SeriesQueryResponse returns matching time series metadata.
message SeriesQueryResponse {
  // Status: "success" or "error"
  string status = 1;

  // Matching series (array of label sets)
  repeated SeriesLabels data = 2;

  // Error message (if status is "error")
  string error = 3;
}

// SeriesLabels represents a single time series' label set.
message SeriesLabels {
  // Label key-value pairs
  map<string, string> labels = 1;
}

// LabelValuesResponse returns unique label values.
message LabelValuesResponse {
  // Status: "success" or "error"
  string status = 1;

  // Unique label values (sorted)
  repeated string data = 2;

  // Error message (if status is "error")
  string error = 3;
}
