// Copyright 2024 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.cloud.batch.v1alpha;

import "google/api/field_behavior.proto";
import "google/api/field_info.proto";
import "google/api/resource.proto";
import "google/cloud/batch/v1alpha/notification.proto";
import "google/protobuf/timestamp.proto";
import "google/type/interval.proto";

option csharp_namespace = "Google.Cloud.Batch.V1Alpha";
option go_package = "cloud.google.com/go/batch/apiv1alpha/batchpb;batchpb";
option java_multiple_files = true;
option java_outer_classname = "ResourceAllowanceProto";
option java_package = "com.google.cloud.batch.v1alpha";
option objc_class_prefix = "GCB";
option php_namespace = "Google\\Cloud\\Batch\\V1alpha";
option ruby_package = "Google::Cloud::Batch::V1alpha";

// A `CalendarPeriod` represents the abstract concept of a time period that
// has a canonical start. All calendar times begin at 12 AM US and Canadian
// Pacific Time (UTC-8).
enum CalendarPeriod {
  // Unspecified.
  CALENDAR_PERIOD_UNSPECIFIED = 0;

  // The month starts on the first date of the month and resets at the beginning
  // of each month.
  MONTH = 1;

  // The quarter starts on dates January 1, April 1, July 1, and October 1 of
  // each year and resets at the beginning of the next quarter.
  QUARTER = 2;

  // The year starts on January 1 and resets at the beginning of the next year.
  YEAR = 3;

  // The week period starts and resets every Monday.
  WEEK = 4;

  // The day starts at 12:00am.
  DAY = 5;
}

// ResourceAllowance valid state.
enum ResourceAllowanceState {
  // Unspecified.
  RESOURCE_ALLOWANCE_STATE_UNSPECIFIED = 0;

  // ResourceAllowance is active and in use.
  RESOURCE_ALLOWANCE_ACTIVE = 1;

  // ResourceAllowance limit is reached.
  RESOURCE_ALLOWANCE_DEPLETED = 2;
}

// The Resource Allowance description for Cloud Batch.
// Only one Resource Allowance is supported now under a specific location and
// project.
message ResourceAllowance {
  option (google.api.resource) = {
    type: "batch.googleapis.com/ResourceAllowance"
    pattern: "projects/{project}/locations/{location}/resourceAllowances/{resource_allowance}"
    plural: "resourceAllowances"
    singular: "resourceAllowance"
  };

  // ResourceAllowance detail.
  oneof resource_allowance {
    // The detail of usage resource allowance.
    UsageResourceAllowance usage_resource_allowance = 4;
  }

  // Identifier. ResourceAllowance name.
  // For example:
  // "projects/123456/locations/us-central1/resourceAllowances/resource-allowance-1".
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Output only. A system generated unique ID (in UUID4 format) for the
  // ResourceAllowance.
  string uid = 2 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OUTPUT_ONLY
  ];

  // Output only. Time when the ResourceAllowance was created.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Labels are attributes that can be set and used by both the
  // user and by Batch. Labels must meet the following constraints:
  //
  // * Keys and values can contain only lowercase letters, numeric characters,
  // underscores, and dashes.
  // * All characters must use UTF-8 encoding, and international characters are
  // allowed.
  // * Keys must start with a lowercase letter or international character.
  // * Each resource is limited to a maximum of 64 labels.
  //
  // Both keys and values are additionally constrained to be <= 128 bytes.
  map<string, string> labels = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Notification configurations.
  repeated Notification notifications = 6
      [(google.api.field_behavior) = OPTIONAL];
}

// UsageResourceAllowance describes the detail of usage resource allowance.
message UsageResourceAllowance {
  // Required. Spec of a usage ResourceAllowance.
  UsageResourceAllowanceSpec spec = 1 [(google.api.field_behavior) = REQUIRED];

  // Output only. Status of a usage ResourceAllowance.
  UsageResourceAllowanceStatus status = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Spec of a usage ResourceAllowance.
message UsageResourceAllowanceSpec {
  // UsageResourceAllowance limitation.
  message Limit {
    oneof duration {
      // Optional. A CalendarPeriod represents the abstract concept of a time
      // period that has a canonical start.
      CalendarPeriod calendar_period = 1
          [(google.api.field_behavior) = OPTIONAL];
    }

    // Required. Limit value of a UsageResourceAllowance within its one
    // duration.
    //
    // Limit cannot be a negative value. Default is 0.
    // For example, you can set `limit` as 10000.0 with duration of the current
    // month by setting `calendar_period` field as monthly. That means in your
    // current month, 10000.0 is the core hour limitation that your resources
    // are allowed to consume.
    optional double limit = 2 [(google.api.field_behavior) = REQUIRED];
  }

  // Required. Spec type is unique for each usage ResourceAllowance.
  // Batch now only supports type as "cpu-core-hours" for CPU usage consumption
  // tracking.
  string type = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Threshold of a UsageResourceAllowance limiting how many resources
  // can be consumed for each type.
  Limit limit = 2 [(google.api.field_behavior) = REQUIRED];
}

// Status of a usage ResourceAllowance.
message UsageResourceAllowanceStatus {
  // UsageResourceAllowanceStatus detail about usage consumption.
  message LimitStatus {
    // Output only. The consumption interval.
    google.type.Interval consumption_interval = 1
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Limit value of a UsageResourceAllowance within its one
    // duration.
    optional double limit = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Accumulated consumption during `consumption_interval`.
    optional double consumed = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  message PeriodConsumption {
    // Output only. The consumption interval.
    google.type.Interval consumption_interval = 1
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Accumulated consumption during `consumption_interval`.
    optional double consumed = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // ConsumptionReport is the report of ResourceAllowance consumptions in a time
  // period.
  message ConsumptionReport {
    // Output only. ResourceAllowance consumptions in the latest calendar
    // period. Key is the calendar period in string format. Batch currently
    // supports HOUR, DAY, MONTH and YEAR.
    map<string, PeriodConsumption> latest_period_consumptions = 1
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Output only. ResourceAllowance state.
  ResourceAllowanceState state = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. ResourceAllowance consumption status for usage resources.
  LimitStatus limit_status = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The report of ResourceAllowance consumptions in a time period.
  ConsumptionReport report = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
}
