// Copyright 2017 Google Inc.
//
// 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.runtimeconfig.v1beta1;

import "google/api/annotations.proto";
import "google/cloud/runtimeconfig/v1beta1/resources.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.RuntimeConfig.V1Beta1";
option go_package = "cloud.google.com/go/runtimeconfig/apiv1beta1/runtimeconfigpb;runtimeconfigpb";
option java_multiple_files = true;
option java_package = "com.google.cloud.runtimeconfig.v1beta1";
option php_namespace = "Google\\Cloud\\RuntimeConfig\\V1beta1";

// RuntimeConfig API represents configuration objects and operations on those
// configuration objects.
// RuntimeConfig objects consist of Variables logically grouped in the those
// objects.
// Variables are simple key-value pairs. Variables can be watched for changes or
// deletions. Variable key can be hieararchical, e.g. ports/serving_port,
// ports/monitoring_port, etc. Variable names can be hierarchical. No variable
// name can be prefix of another.
// Config objects represent logical containers for variables, e.g. flags,
// passwords, etc.
service RuntimeConfigManager {
  // Lists all the RuntimeConfig resources within project.
  rpc ListConfigs(ListConfigsRequest) returns (ListConfigsResponse) {
    option (google.api.http) = {
      get: "/v1beta1/{parent=projects/*}/configs"
    };
  }

  // Gets information about a RuntimeConfig resource.
  rpc GetConfig(GetConfigRequest) returns (RuntimeConfig) {
    option (google.api.http) = {
      get: "/v1beta1/{name=projects/*/configs/*}"
    };
  }

  // Creates a new RuntimeConfig resource. The configuration name must be
  // unique within project.
  rpc CreateConfig(CreateConfigRequest) returns (RuntimeConfig) {
    option (google.api.http) = {
      post: "/v1beta1/{parent=projects/*}/configs"
      body: "config"
    };
  }

  // Updates a RuntimeConfig resource. The configuration must exist beforehand.
  rpc UpdateConfig(UpdateConfigRequest) returns (RuntimeConfig) {
    option (google.api.http) = {
      put: "/v1beta1/{name=projects/*/configs/*}"
      body: "config"
    };
  }

  // Deletes a RuntimeConfig resource.
  rpc DeleteConfig(DeleteConfigRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1beta1/{name=projects/*/configs/*}"
    };
  }

  // Lists variables within given a configuration, matching any provided
  // filters. This only lists variable names, not the values, unless
  // `return_values` is true, in which case only variables that user has IAM
  // permission to GetVariable will be returned.
  rpc ListVariables(ListVariablesRequest) returns (ListVariablesResponse) {
    option (google.api.http) = {
      get: "/v1beta1/{parent=projects/*/configs/*}/variables"
    };
  }

  // Gets information about a single variable.
  rpc GetVariable(GetVariableRequest) returns (Variable) {
    option (google.api.http) = {
      get: "/v1beta1/{name=projects/*/configs/*/variables/**}"
    };
  }

  // Watches a specific variable and waits for a change in the variable's value.
  // When there is a change, this method returns the new value or times out.
  //
  // If a variable is deleted while being watched, the `variableState` state is
  // set to `DELETED` and the method returns the last known variable `value`.
  //
  // If you set the deadline for watching to a larger value than internal
  // timeout (60 seconds), the current variable value is returned and the
  // `variableState` will be `VARIABLE_STATE_UNSPECIFIED`.
  //
  // To learn more about creating a watcher, read the
  // [Watching a Variable for
  // Changes](/deployment-manager/runtime-configurator/watching-a-variable)
  // documentation.
  rpc WatchVariable(WatchVariableRequest) returns (Variable) {
    option (google.api.http) = {
      post: "/v1beta1/{name=projects/*/configs/*/variables/**}:watch"
      body: "*"
    };
  }

  // Creates a variable within the given configuration. You cannot create
  // a variable with a name that is a prefix of an existing variable name, or a
  // name that has an existing variable name as a prefix.
  //
  // To learn more about creating a variable, read the
  // [Setting and Getting
  // Data](/deployment-manager/runtime-configurator/set-and-get-variables)
  // documentation.
  rpc CreateVariable(CreateVariableRequest) returns (Variable) {
    option (google.api.http) = {
      post: "/v1beta1/{parent=projects/*/configs/*}/variables"
      body: "variable"
    };
  }

  // Updates an existing variable with a new value.
  rpc UpdateVariable(UpdateVariableRequest) returns (Variable) {
    option (google.api.http) = {
      put: "/v1beta1/{name=projects/*/configs/*/variables/**}"
      body: "variable"
    };
  }

  // Deletes a variable or multiple variables.
  //
  // If you specify a variable name, then that variable is deleted. If you
  // specify a prefix and `recursive` is true, then all variables with that
  // prefix are deleted. You must set a `recursive` to true if you delete
  // variables by prefix.
  rpc DeleteVariable(DeleteVariableRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1beta1/{name=projects/*/configs/*/variables/**}"
    };
  }

  // List waiters within the given configuration.
  rpc ListWaiters(ListWaitersRequest) returns (ListWaitersResponse) {
    option (google.api.http) = {
      get: "/v1beta1/{parent=projects/*/configs/*}/waiters"
    };
  }

  // Gets information about a single waiter.
  rpc GetWaiter(GetWaiterRequest) returns (Waiter) {
    option (google.api.http) = {
      get: "/v1beta1/{name=projects/*/configs/*/waiters/*}"
    };
  }

  // Creates a Waiter resource. This operation returns a long-running Operation
  // resource which can be polled for completion. However, a waiter with the
  // given name will exist (and can be retrieved) prior to the operation
  // completing. If the operation fails, the failed Waiter resource will
  // still exist and must be deleted prior to subsequent creation attempts.
  rpc CreateWaiter(CreateWaiterRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1beta1/{parent=projects/*/configs/*}/waiters"
      body: "waiter"
    };
  }

  // Deletes the waiter with the specified name.
  rpc DeleteWaiter(DeleteWaiterRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1beta1/{name=projects/*/configs/*/waiters/*}"
    };
  }
}

// Request for the `ListConfigs()` method.
message ListConfigsRequest {
  // The [project
  // ID](https://support.google.com/cloud/answer/6158840?hl=en&ref_topic=6158848)
  // for this request, in the format `projects/[PROJECT_ID]`.
  string parent = 1;

  // Specifies the number of results to return per page. If there are fewer
  // elements than the specified number, returns all elements.
  int32 page_size = 2;

  // Specifies a page token to use. Set `pageToken` to a `nextPageToken`
  // returned by a previous list request to get the next page of results.
  string page_token = 3;
}

// `ListConfigs()` returns the following response. The order of returned
// objects is arbitrary; that is, it is not ordered in any particular way.
message ListConfigsResponse {
  // A list of the configurations in the project. The order of returned
  // objects is arbitrary; that is, it is not ordered in any particular way.
  repeated RuntimeConfig configs = 1;

  // This token allows you to get the next page of results for list requests.
  // If the number of results is larger than `pageSize`, use the `nextPageToken`
  // as a value for the query parameter `pageToken` in the next list request.
  // Subsequent list requests will have their own `nextPageToken` to continue
  // paging through the results
  string next_page_token = 2;
}

// Gets a RuntimeConfig resource.
message GetConfigRequest {
  // The name of the RuntimeConfig resource to retrieve, in the format:
  //
  // `projects/[PROJECT_ID]/configs/[CONFIG_NAME]`
  string name = 2;
}

// Creates a RuntimeConfig resource.
message CreateConfigRequest {
  // The [project
  // ID](https://support.google.com/cloud/answer/6158840?hl=en&ref_topic=6158848)
  // for this request, in the format `projects/[PROJECT_ID]`.
  string parent = 1;

  // The RuntimeConfig to create.
  RuntimeConfig config = 2;

  // An optional but recommended unique `request_id`. If the server
  // receives two `create()` requests  with the same
  // `request_id`, then the second request will be ignored and the
  // first resource created and stored in the backend is returned.
  // Empty `request_id` fields are ignored.
  //
  // It is responsibility of the client to ensure uniqueness of the
  // `request_id` strings.
  //
  // `request_id` strings are limited to 64 characters.
  string request_id = 3;
}

// Request message for `UpdateConfig()` method.
message UpdateConfigRequest {
  // The name of the RuntimeConfig resource to update, in the format:
  //
  // `projects/[PROJECT_ID]/configs/[CONFIG_NAME]`
  string name = 1;

  // The config resource to update.
  RuntimeConfig config = 2;
}

// Request for the `DeleteConfig()` method.
message DeleteConfigRequest {
  // The RuntimeConfig resource to delete, in the format:
  //
  // `projects/[PROJECT_ID]/configs/[CONFIG_NAME]`
  string name = 1;
}

// Request for the `ListVariables()` method.
message ListVariablesRequest {
  // The path to the RuntimeConfig resource for which you want to list
  // variables. The configuration must exist beforehand; the path must by in the
  // format:
  //
  // `projects/[PROJECT_ID]/configs/[CONFIG_NAME]`
  string parent = 1;

  // Filters variables by matching the specified filter. For example:
  //
  // `projects/example-project/config/[CONFIG_NAME]/variables/example-variable`.
  string filter = 2;

  // Specifies the number of results to return per page. If there are fewer
  // elements than the specified number, returns all elements.
  int32 page_size = 3;

  // Specifies a page token to use. Set `pageToken` to a `nextPageToken`
  // returned by a previous list request to get the next page of results.
  string page_token = 4;

  // The flag indicates whether the user wants to return values of variables.
  // If true, then only those variables that user has IAM GetVariable permission
  // will be returned along with their values.
  bool return_values = 5;
}

// Response for the `ListVariables()` method.
message ListVariablesResponse {
  // A list of variables and their values. The order of returned variable
  // objects is arbitrary.
  repeated Variable variables = 1;

  // This token allows you to get the next page of results for list requests.
  // If the number of results is larger than `pageSize`, use the `nextPageToken`
  // as a value for the query parameter `pageToken` in the next list request.
  // Subsequent list requests will have their own `nextPageToken` to continue
  // paging through the results
  string next_page_token = 2;
}

// Request for the `WatchVariable()` method.
message WatchVariableRequest {
  // The name of the variable to watch, in the format:
  //
  // `projects/[PROJECT_ID]/configs/[CONFIG_NAME]`
  string name = 1;

  // If specified, checks the current timestamp of the variable and if the
  // current timestamp is newer than `newerThan` timestamp, the method returns
  // immediately.
  //
  // If not specified or the variable has an older timestamp, the watcher waits
  // for a the value to change before returning.
  google.protobuf.Timestamp newer_than = 4;
}

// Request for the `GetVariable()` method.
message GetVariableRequest {
  // The name of the variable to return, in the format:
  //
  // `projects/[PROJECT_ID]/configs/[CONFIG_NAME]/variables/[VARIBLE_NAME]`
  string name = 1;
}

// Request for the `CreateVariable()` method.
message CreateVariableRequest {
  // The path to the RutimeConfig resource that this variable should belong to.
  // The configuration must exist beforehand; the path must by in the format:
  //
  // `projects/[PROJECT_ID]/configs/[CONFIG_NAME]`
  string parent = 1;

  // The variable to create.
  Variable variable = 2;

  // An optional but recommended unique `request_id`. If the server
  // receives two `create()` requests  with the same
  // `request_id`, then the second request will be ignored and the
  // first resource created and stored in the backend is returned.
  // Empty `request_id` fields are ignored.
  //
  // It is responsibility of the client to ensure uniqueness of the
  // `request_id` strings.
  //
  // `request_id` strings are limited to 64 characters.
  string request_id = 3;
}

// Request for the `UpdateVariable()` method.
message UpdateVariableRequest {
  // The name of the variable to update, in the format:
  //
  // `projects/[PROJECT_ID]/configs/[CONFIG_NAME]/variables/[VARIABLE_NAME]`
  string name = 1;

  // The variable to update.
  Variable variable = 2;
}

// Request for the `DeleteVariable()` method.
message DeleteVariableRequest {
  // The name of the variable to delete, in the format:
  //
  // `projects/[PROJECT_ID]/configs/[CONFIG_NAME]/variables/[VARIABLE_NAME]`
  string name = 1;

  // Set to `true` to recursively delete multiple variables with the same
  // prefix.
  bool recursive = 2;
}

// Request for the `ListWaiters()` method.
message ListWaitersRequest {
  // The path to the configuration for which you want to get a list of waiters.
  // The configuration must exist beforehand; the path must by in the format:
  //
  // `projects/[PROJECT_ID]/configs/[CONFIG_NAME]`
  string parent = 1;

  // Specifies the number of results to return per page. If there are fewer
  // elements than the specified number, returns all elements.
  int32 page_size = 2;

  // Specifies a page token to use. Set `pageToken` to a `nextPageToken`
  // returned by a previous list request to get the next page of results.
  string page_token = 3;
}

// Response for the `ListWaiters()` method.
// Order of returned waiter objects is arbitrary.
message ListWaitersResponse {
  // Found waiters in the project.
  repeated Waiter waiters = 1;

  // This token allows you to get the next page of results for list requests.
  // If the number of results is larger than `pageSize`, use the `nextPageToken`
  // as a value for the query parameter `pageToken` in the next list request.
  // Subsequent list requests will have their own `nextPageToken` to continue
  // paging through the results
  string next_page_token = 2;
}

// Request for the `GetWaiter()` method.
message GetWaiterRequest {
  // The fully-qualified name of the Waiter resource object to retrieve, in the
  // format:
  //
  // `projects/[PROJECT_ID]/configs/[CONFIG_NAME]/waiters/[WAITER_NAME]`
  string name = 1;
}

// Request message for `CreateWaiter()` method.
message CreateWaiterRequest {
  // The path to the configuration that will own the waiter.
  // The configuration must exist beforehand; the path must by in the format:
  //
  // `projects/[PROJECT_ID]/configs/[CONFIG_NAME]`.
  string parent = 1;

  // The Waiter resource to create.
  Waiter waiter = 2;

  // An optional but recommended unique `request_id`. If the server
  // receives two `create()` requests  with the same
  // `request_id`, then the second request will be ignored and the
  // first resource created and stored in the backend is returned.
  // Empty `request_id` fields are ignored.
  //
  // It is responsibility of the client to ensure uniqueness of the
  // `request_id` strings.
  //
  // `request_id` strings are limited to 64 characters.
  string request_id = 3;
}

// Request for the `DeleteWaiter()` method.
message DeleteWaiterRequest {
  // The Waiter resource to delete, in the format:
  //
  //  `projects/[PROJECT_ID]/configs/[CONFIG_NAME]/waiters/[WAITER_NAME]`
  string name = 1;
}
