// 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.cloud.backupdr.v1;

import "google/api/field_behavior.proto";
import "google/api/field_info.proto";
import "google/api/resource.proto";
import "google/protobuf/timestamp.proto";
import "google/type/dayofweek.proto";
import "google/type/month.proto";

option csharp_namespace = "Google.Cloud.BackupDR.V1";
option go_package = "cloud.google.com/go/backupdr/apiv1/backupdrpb;backupdrpb";
option java_multiple_files = true;
option java_outer_classname = "BackupPlanProto";
option java_package = "com.google.cloud.backupdr.v1";
option php_namespace = "Google\\Cloud\\BackupDR\\V1";
option ruby_package = "Google::Cloud::BackupDR::V1";

// A `BackupPlan` specifies some common fields, such as `description` as well
// as one or more `BackupRule` messages. Each `BackupRule` has a retention
// policy and defines a schedule by which the system is to perform backup
// workloads.
message BackupPlan {
  option (google.api.resource) = {
    type: "backupdr.googleapis.com/BackupPlan"
    pattern: "projects/{project}/locations/{location}/backupPlans/{backup_plan}"
    plural: "backupPlans"
    singular: "backupPlan"
  };

  // `State` enumerates the possible states for a `BackupPlan`.
  enum State {
    // State not set.
    STATE_UNSPECIFIED = 0;

    // The resource is being created.
    CREATING = 1;

    // The resource has been created and is fully usable.
    ACTIVE = 2;

    // The resource is being deleted.
    DELETING = 3;

    // The resource has been created but is not usable.
    INACTIVE = 4;
  }

  // Output only. Identifier. The resource name of the `BackupPlan`.
  //
  // Format: `projects/{project}/locations/{location}/backupPlans/{backup_plan}`
  string name = 1 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.field_behavior) = IDENTIFIER
  ];

  // Optional. The description of the `BackupPlan` resource.
  //
  // The description allows for additional details about `BackupPlan` and its
  // use cases to be provided. An example description is the following:  "This
  // is a backup plan that performs a daily backup at 6pm and retains data for 3
  // months". The description must be at most 2048 characters.
  string description = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. This collection of key/value pairs allows for custom labels to be
  // supplied by the user.  Example, {"tag": "Weekly"}.
  map<string, string> labels = 3 [(google.api.field_behavior) = OPTIONAL];

  // Output only. When the `BackupPlan` was created.
  google.protobuf.Timestamp create_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. When the `BackupPlan` was last updated.
  google.protobuf.Timestamp update_time = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. The backup rules for this `BackupPlan`. There must be at least
  // one `BackupRule` message.
  repeated BackupRule backup_rules = 6 [(google.api.field_behavior) = REQUIRED];

  // Output only. The `State` for the `BackupPlan`.
  State state = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. The resource type to which the `BackupPlan` will be applied.
  // Examples include, "compute.googleapis.com/Instance",
  // "sqladmin.googleapis.com/Instance", or "alloydb.googleapis.com/Cluster".
  string resource_type = 8 [(google.api.field_behavior) = REQUIRED];

  // Optional. `etag` is returned from the service in the response. As a user of
  // the service, you may provide an etag value in this field to prevent stale
  // resources.
  string etag = 9 [(google.api.field_behavior) = OPTIONAL];

  // Required. Resource name of backup vault which will be used as storage
  // location for backups. Format:
  // projects/{project}/locations/{location}/backupVaults/{backupvault}
  string backup_vault = 10 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "backupdr.googleapis.com/BackupVault"
    }
  ];

  // Output only. The Google Cloud Platform Service Account to be used by the
  // BackupVault for taking backups. Specify the email address of the Backup
  // Vault Service Account.
  string backup_vault_service_account = 11
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// `BackupRule` binds the backup schedule to a retention policy.
message BackupRule {
  // Required. Immutable. The unique id of this `BackupRule`. The `rule_id` is
  // unique per `BackupPlan`.The `rule_id` must start with a lowercase letter
  // followed by up to 62 lowercase letters, numbers, or hyphens. Pattern,
  // /[a-z][a-z0-9-]{,62}/.
  string rule_id = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Required. Configures the duration for which backup data will be kept. It is
  // defined in “days”. The value should be greater than or equal to minimum
  // enforced retention of the backup vault.
  //
  // Minimum value is 1 and maximum value is 90 for hourly backups.
  // Minimum value is 1 and maximum value is 90 for daily backups.
  // Minimum value is 7 and maximum value is 186 for weekly backups.
  // Minimum value is 30 and maximum value is 732 for monthly backups.
  // Minimum value is 365 and maximum value is 36159 for yearly backups.
  int32 backup_retention_days = 4 [(google.api.field_behavior) = REQUIRED];

  // The schedule that defines the automated backup workloads for this
  // `BackupRule`.
  oneof backup_schedule_oneof {
    // Required. Defines a schedule that runs within the confines of a defined
    // window of time.
    StandardSchedule standard_schedule = 5
        [(google.api.field_behavior) = REQUIRED];
  }
}

// `StandardSchedule` defines a schedule that run within the confines of a
// defined window of days. We can define recurrence type for schedule as
// HOURLY, DAILY, WEEKLY, MONTHLY or YEARLY.
message StandardSchedule {
  // `RecurrenceTypes` enumerates the applicable periodicity for the schedule.
  enum RecurrenceType {
    // recurrence type not set
    RECURRENCE_TYPE_UNSPECIFIED = 0;

    // The `BackupRule` is to be applied hourly.
    HOURLY = 1;

    // The `BackupRule` is to be applied daily.
    DAILY = 2;

    // The `BackupRule` is to be applied weekly.
    WEEKLY = 3;

    // The `BackupRule` is to be applied monthly.
    MONTHLY = 4;

    // The `BackupRule` is to be applied yearly.
    YEARLY = 5;
  }

  // Required. Specifies the `RecurrenceType` for the schedule.
  RecurrenceType recurrence_type = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. Specifies frequency for hourly backups. A hourly frequency of 2
  // means jobs will run every 2 hours from start time till end time defined.
  //
  // This is required for `recurrence_type`, `HOURLY` and is not applicable
  // otherwise. A validation error will occur if a value is supplied and
  // `recurrence_type` is not `HOURLY`.
  //
  // Value of hourly frequency should be between 6 and 23.
  //
  // Reason for limit : We found that there is bandwidth limitation of 3GB/S for
  // GMI while taking a backup and 5GB/S while doing a restore. Given the amount
  // of parallel backups and restore we are targeting, this will potentially
  // take the backup time to mins and hours (in worst case scenario).
  int32 hourly_frequency = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Specifies days of week like, MONDAY or TUESDAY, on which jobs
  // will run.
  //
  // This is required for `recurrence_type`, `WEEKLY` and is not applicable
  // otherwise. A validation error will occur if a value is supplied and
  // `recurrence_type` is not `WEEKLY`.
  repeated google.type.DayOfWeek days_of_week = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Specifies days of months like 1, 5, or 14 on which jobs will run.
  //
  // Values for `days_of_month` are only applicable for `recurrence_type`,
  // `MONTHLY` and `YEARLY`. A validation error will occur if other values are
  // supplied.
  repeated int32 days_of_month = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Specifies a week day of the month like, FIRST SUNDAY or LAST
  // MONDAY, on which jobs will run. This will be specified by two fields in
  // `WeekDayOfMonth`, one for the day, e.g. `MONDAY`, and one for the week,
  // e.g. `LAST`.
  //
  // This field is only applicable for `recurrence_type`, `MONTHLY` and
  // `YEARLY`. A validation error will occur if other values are supplied.
  WeekDayOfMonth week_day_of_month = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Specifies the months of year, like `FEBRUARY` and/or `MAY`, on
  // which jobs will run.
  //
  // This field is only applicable when `recurrence_type` is `YEARLY`. A
  // validation error will occur if other values are supplied.
  repeated google.type.Month months = 6
      [(google.api.field_behavior) = OPTIONAL];

  // Required. A BackupWindow defines the window of day during which backup jobs
  // will run. Jobs are queued at the beginning of the window and will be marked
  // as `NOT_RUN` if they do not start by the end of the window.
  //
  // Note: running jobs will not be cancelled at the end of the window.
  BackupWindow backup_window = 7 [(google.api.field_behavior) = REQUIRED];

  // Required. The time zone to be used when interpreting the schedule.
  // The value of this field must be a time zone name from the IANA tz database.
  // See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones for the
  // list of valid timezone names. For e.g., Europe/Paris.
  string time_zone = 8 [(google.api.field_behavior) = REQUIRED];
}

// `BackupWindow` defines a window of the day during which backup jobs will run.
message BackupWindow {
  // Required. The hour of day (0-23) when the window starts for e.g. if value
  // of start hour of day is 6 that mean backup window start at 6:00.
  int32 start_hour_of_day = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The hour of day (1-24) when the window end for e.g. if value of
  // end hour of day is 10 that mean backup window end time is 10:00.
  //
  // End hour of day should be greater than start hour of day.
  // 0 <= start_hour_of_day < end_hour_of_day <= 24
  //
  // End hour of day is not include in backup window that mean if
  // end_hour_of_day= 10 jobs should start before 10:00.
  int32 end_hour_of_day = 2 [(google.api.field_behavior) = REQUIRED];
}

// `WeekDayOfMonth` defines the week day of the month on which the backups will
// run. The message combines a `WeekOfMonth` and `DayOfWeek` to produce values
// like `FIRST`/`MONDAY` or `LAST`/`FRIDAY`.
message WeekDayOfMonth {
  // `WeekOfMonth` enumerates possible weeks in the month, e.g. the first,
  // third, or last week of the month.
  enum WeekOfMonth {
    // The zero value. Do not use.
    WEEK_OF_MONTH_UNSPECIFIED = 0;

    // The first week of the month.
    FIRST = 1;

    // The second week of the month.
    SECOND = 2;

    // The third week of the month.
    THIRD = 3;

    // The fourth  week of the month.
    FOURTH = 4;

    // The last  week of the month.
    LAST = 5;
  }

  // Required. Specifies the week of the month.
  WeekOfMonth week_of_month = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Specifies the day of the week.
  google.type.DayOfWeek day_of_week = 2
      [(google.api.field_behavior) = REQUIRED];
}

// The request message for creating a `BackupPlan`.
message CreateBackupPlanRequest {
  // Required. The `BackupPlan` project and location in the format
  // `projects/{project}/locations/{location}`. In Cloud BackupDR locations
  // map to GCP regions, for example **us-central1**.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "backupdr.googleapis.com/BackupPlan"
    }
  ];

  // Required. The name of the `BackupPlan` to create. The name must be unique
  // for the specified project and location.The name must start with a lowercase
  // letter followed by up to 62 lowercase letters, numbers, or hyphens.
  // Pattern, /[a-z][a-z0-9-]{,62}/.
  string backup_plan_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The `BackupPlan` resource object to create.
  BackupPlan backup_plan = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. An optional request ID to identify requests. Specify a unique
  // request ID so that if you must retry your request, the server will know to
  // ignore the request if it has already been completed. The server will
  // guarantee that for at least 60 minutes since the first request.
  //
  // For example, consider a situation where you make an initial request and t
  // he request times out. If you make the request again with the same request
  // ID, the server can check if original operation with the same request ID
  // was received, and if so, will ignore the second request. This prevents
  // clients from accidentally creating duplicate commitments.
  //
  // The request ID must be a valid UUID with the exception that zero UUID is
  // not supported (00000000-0000-0000-0000-000000000000).
  string request_id = 4 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OPTIONAL
  ];
}

// The request message for getting a list `BackupPlan`.
message ListBackupPlansRequest {
  // Required. The project and location for which to retrieve `BackupPlans`
  // information. Format: `projects/{project}/locations/{location}`. In Cloud
  // BackupDR, locations map to GCP regions, for e.g. **us-central1**. To
  // retrieve backup plans for all locations, use "-" for the
  // `{location}` value.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "backupdr.googleapis.com/BackupPlan"
    }
  ];

  // Optional. The maximum number of `BackupPlans` to return in a single
  // response. If not specified, a default value will be chosen by the service.
  // Note that the response may include a partial list and a caller should
  // only rely on the response's
  // [next_page_token][google.cloud.backupdr.v1.ListBackupPlansResponse.next_page_token]
  // to determine if there are more instances left to be queried.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The value of
  // [next_page_token][google.cloud.backupdr.v1.ListBackupPlansResponse.next_page_token]
  // received from a previous `ListBackupPlans` call.
  // Provide this to retrieve the subsequent page in a multi-page list of
  // results. When paginating, all other parameters provided to
  // `ListBackupPlans` must match the call that provided the page token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Field match expression used to filter the results.
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Field by which to sort the results.
  string order_by = 5 [(google.api.field_behavior) = OPTIONAL];
}

// The response message for getting a list of `BackupPlan`.
message ListBackupPlansResponse {
  // The list of `BackupPlans` in the project for the specified
  // location.
  //
  // If the `{location}` value in the request is "-", the response contains a
  // list of resources from all locations. In case any location is unreachable,
  // the response will only return backup plans in reachable locations and
  // the 'unreachable' field will be populated with a list of unreachable
  // locations.
  // BackupPlan
  repeated BackupPlan backup_plans = 1;

  // A token which may be sent as
  // [page_token][google.cloud.backupdr.v1.ListBackupPlansRequest.page_token] in
  // a subsequent `ListBackupPlans` call to retrieve the next page of results.
  // If this field is omitted or empty, then there are no more results to
  // return.
  string next_page_token = 2;

  // Locations that could not be reached.
  repeated string unreachable = 3;
}

// The request message for getting a `BackupPlan`.
message GetBackupPlanRequest {
  // Required. The resource name of the `BackupPlan` to retrieve.
  //
  // Format: `projects/{project}/locations/{location}/backupPlans/{backup_plan}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "backupdr.googleapis.com/BackupPlan"
    }
  ];
}

// The request message for deleting a `BackupPlan`.
message DeleteBackupPlanRequest {
  // Required. The resource name of the `BackupPlan` to delete.
  //
  // Format: `projects/{project}/locations/{location}/backupPlans/{backup_plan}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "backupdr.googleapis.com/BackupPlan"
    }
  ];

  // Optional. An optional request ID to identify requests. Specify a unique
  // request ID so that if you must retry your request, the server will know to
  // ignore the request if it has already been completed. The server will
  // guarantee that for at least 60 minutes after the first request.
  //
  // For example, consider a situation where you make an initial request and
  // the request times out. If you make the request again with the same request
  // ID, the server can check if original operation with the same request ID
  // was received, and if so, will ignore the second request. This prevents
  // clients from accidentally creating duplicate commitments.
  //
  // The request ID must be a valid UUID with the exception that zero UUID is
  // not supported (00000000-0000-0000-0000-000000000000).
  string request_id = 2 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OPTIONAL
  ];
}
