// Copyright 2025 Google LLC
//
// 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.

syntax = "proto3";

package google.analytics.admin.v1alpha;

option go_package = "cloud.google.com/go/analytics/admin/apiv1alpha/adminpb;adminpb";
option java_multiple_files = true;
option java_outer_classname = "AccessReportProto";
option java_package = "com.google.analytics.admin.v1alpha";

// Dimensions are attributes of your data. For example, the dimension
// `userEmail` indicates the email of the user that accessed reporting data.
// Dimension values in report responses are strings.
message AccessDimension {
  // The API name of the dimension. See [Data Access
  // Schema](https://developers.google.com/analytics/devguides/config/admin/v1/access-api-schema)
  // for the list of dimensions supported in this API.
  //
  // Dimensions are referenced by name in `dimensionFilter` and `orderBys`.
  string dimension_name = 1;
}

// The quantitative measurements of a report. For example, the metric
// `accessCount` is the total number of data access records.
message AccessMetric {
  // The API name of the metric. See [Data Access
  // Schema](https://developers.google.com/analytics/devguides/config/admin/v1/access-api-schema)
  // for the list of metrics supported in this API.
  //
  // Metrics are referenced by name in `metricFilter` & `orderBys`.
  string metric_name = 1;
}

// A contiguous range of days: startDate, startDate + 1, ..., endDate.
message AccessDateRange {
  // The inclusive start date for the query in the format `YYYY-MM-DD`. Cannot
  // be after `endDate`. The format `NdaysAgo`, `yesterday`, or `today` is also
  // accepted, and in that case, the date is inferred based on the current time
  // in the request's time zone.
  string start_date = 1;

  // The inclusive end date for the query in the format `YYYY-MM-DD`. Cannot
  // be before `startDate`. The format `NdaysAgo`, `yesterday`, or `today` is
  // also accepted, and in that case, the date is inferred based on the current
  // time in the request's time zone.
  string end_date = 2;
}

// Expresses dimension or metric filters. The fields in the same expression need
// to be either all dimensions or all metrics.
message AccessFilterExpression {
  // Specify one type of filter expression for `FilterExpression`.
  oneof one_expression {
    // Each of the FilterExpressions in the and_group has an AND relationship.
    AccessFilterExpressionList and_group = 1;

    // Each of the FilterExpressions in the or_group has an OR relationship.
    AccessFilterExpressionList or_group = 2;

    // The FilterExpression is NOT of not_expression.
    AccessFilterExpression not_expression = 3;

    // A primitive filter. In the same FilterExpression, all of the filter's
    // field names need to be either all dimensions or all metrics.
    AccessFilter access_filter = 4;
  }
}

// A list of filter expressions.
message AccessFilterExpressionList {
  // A list of filter expressions.
  repeated AccessFilterExpression expressions = 1;
}

// An expression to filter dimension or metric values.
message AccessFilter {
  // Specify one type of filter for `Filter`.
  oneof one_filter {
    // Strings related filter.
    AccessStringFilter string_filter = 2;

    // A filter for in list values.
    AccessInListFilter in_list_filter = 3;

    // A filter for numeric or date values.
    AccessNumericFilter numeric_filter = 4;

    // A filter for two values.
    AccessBetweenFilter between_filter = 5;
  }

  // The dimension name or metric name.
  string field_name = 1;
}

// The filter for strings.
message AccessStringFilter {
  // The match type of a string filter.
  enum MatchType {
    // Unspecified
    MATCH_TYPE_UNSPECIFIED = 0;

    // Exact match of the string value.
    EXACT = 1;

    // Begins with the string value.
    BEGINS_WITH = 2;

    // Ends with the string value.
    ENDS_WITH = 3;

    // Contains the string value.
    CONTAINS = 4;

    // Full match for the regular expression with the string value.
    FULL_REGEXP = 5;

    // Partial match for the regular expression with the string value.
    PARTIAL_REGEXP = 6;
  }

  // The match type for this filter.
  MatchType match_type = 1;

  // The string value used for the matching.
  string value = 2;

  // If true, the string value is case sensitive.
  bool case_sensitive = 3;
}

// The result needs to be in a list of string values.
message AccessInListFilter {
  // The list of string values. Must be non-empty.
  repeated string values = 1;

  // If true, the string value is case sensitive.
  bool case_sensitive = 2;
}

// Filters for numeric or date values.
message AccessNumericFilter {
  // The operation applied to a numeric filter.
  enum Operation {
    // Unspecified.
    OPERATION_UNSPECIFIED = 0;

    // Equal
    EQUAL = 1;

    // Less than
    LESS_THAN = 2;

    // Less than or equal
    LESS_THAN_OR_EQUAL = 3;

    // Greater than
    GREATER_THAN = 4;

    // Greater than or equal
    GREATER_THAN_OR_EQUAL = 5;
  }

  // The operation type for this filter.
  Operation operation = 1;

  // A numeric value or a date value.
  NumericValue value = 2;
}

// To express that the result needs to be between two numbers (inclusive).
message AccessBetweenFilter {
  // Begins with this number.
  NumericValue from_value = 1;

  // Ends with this number.
  NumericValue to_value = 2;
}

// To represent a number.
message NumericValue {
  // One of a numeric value
  oneof one_value {
    // Integer value
    int64 int64_value = 1;

    // Double value
    double double_value = 2;
  }
}

// Order bys define how rows will be sorted in the response. For example,
// ordering rows by descending access count is one ordering, and ordering rows
// by the country string is a different ordering.
message AccessOrderBy {
  // Sorts by metric values.
  message MetricOrderBy {
    // A metric name in the request to order by.
    string metric_name = 1;
  }

  // Sorts by dimension values.
  message DimensionOrderBy {
    // Rule to order the string dimension values by.
    enum OrderType {
      // Unspecified.
      ORDER_TYPE_UNSPECIFIED = 0;

      // Alphanumeric sort by Unicode code point. For example, "2" < "A" < "X" <
      // "b" < "z".
      ALPHANUMERIC = 1;

      // Case insensitive alphanumeric sort by lower case Unicode code point.
      // For example, "2" < "A" < "b" < "X" < "z".
      CASE_INSENSITIVE_ALPHANUMERIC = 2;

      // Dimension values are converted to numbers before sorting. For example
      // in NUMERIC sort, "25" < "100", and in `ALPHANUMERIC` sort, "100" <
      // "25". Non-numeric dimension values all have equal ordering value below
      // all numeric values.
      NUMERIC = 3;
    }

    // A dimension name in the request to order by.
    string dimension_name = 1;

    // Controls the rule for dimension value ordering.
    OrderType order_type = 2;
  }

  // Specify one type of order by for `OrderBy`.
  oneof one_order_by {
    // Sorts results by a metric's values.
    MetricOrderBy metric = 1;

    // Sorts results by a dimension's values.
    DimensionOrderBy dimension = 2;
  }

  // If true, sorts by descending order. If false or unspecified, sorts in
  // ascending order.
  bool desc = 3;
}

// Describes a dimension column in the report. Dimensions requested in a report
// produce column entries within rows and DimensionHeaders. However, dimensions
// used exclusively within filters or expressions do not produce columns in a
// report; correspondingly, those dimensions do not produce headers.
message AccessDimensionHeader {
  // The dimension's name; for example 'userEmail'.
  string dimension_name = 1;
}

// Describes a metric column in the report. Visible metrics requested in a
// report produce column entries within rows and MetricHeaders. However,
// metrics used exclusively within filters or expressions do not produce columns
// in a report; correspondingly, those metrics do not produce headers.
message AccessMetricHeader {
  // The metric's name; for example 'accessCount'.
  string metric_name = 1;
}

// Access report data for each row.
message AccessRow {
  // List of dimension values. These values are in the same order as specified
  // in the request.
  repeated AccessDimensionValue dimension_values = 1;

  // List of metric values. These values are in the same order as specified
  // in the request.
  repeated AccessMetricValue metric_values = 2;
}

// The value of a dimension.
message AccessDimensionValue {
  // The dimension value. For example, this value may be 'France' for the
  // 'country' dimension.
  string value = 1;
}

// The value of a metric.
message AccessMetricValue {
  // The measurement value. For example, this value may be '13'.
  string value = 1;
}

// Current state of all quotas for this Analytics property. If any quota for a
// property is exhausted, all requests to that property will return Resource
// Exhausted errors.
message AccessQuota {
  // Properties can use 250,000 tokens per day. Most requests consume fewer than
  // 10 tokens.
  AccessQuotaStatus tokens_per_day = 1;

  // Properties can use 50,000 tokens per hour. An API request consumes a single
  // number of tokens, and that number is deducted from all of the hourly,
  // daily, and per project hourly quotas.
  AccessQuotaStatus tokens_per_hour = 2;

  // Properties can use up to 50 concurrent requests.
  AccessQuotaStatus concurrent_requests = 3;

  // Properties and cloud project pairs can have up to 50 server errors per
  // hour.
  AccessQuotaStatus server_errors_per_project_per_hour = 4;

  // Properties can use up to 25% of their tokens per project per hour. This
  // amounts to Analytics 360 Properties can use 12,500 tokens per project per
  // hour. An API request consumes a single number of tokens, and that number is
  // deducted from all of the hourly, daily, and per project hourly quotas.
  AccessQuotaStatus tokens_per_project_per_hour = 5;
}

// Current state for a particular quota group.
message AccessQuotaStatus {
  // Quota consumed by this request.
  int32 consumed = 1;

  // Quota remaining after this request.
  int32 remaining = 2;
}
