// Copyright 2021 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.resourcesettings.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";

option cc_enable_arenas = true;
option go_package = "cloud.google.com/go/resourcesettings/apiv1/resourcesettingspb;resourcesettingspb";
option java_multiple_files = true;
option java_outer_classname = "ResourceSettingsProto";
option java_package = "com.google.cloud.resourcesettings.v1";

// Client library namespace
option csharp_namespace = "Google.Cloud.ResourceSettings.V1";
option php_namespace = "Google\\Cloud\\ResourceSettings\\V1";
option ruby_package = "Google::Cloud::ResourceSettings::V1";

// An interface to interact with resource settings and setting values throughout
// the resource hierarchy.
//
// Services may surface a number of settings for users to control how their
// resources behave. Values of settings applied on a given Cloud resource are
// evaluated hierarchically and inherited by all descendants of that resource.
//
// For all requests, returns a `google.rpc.Status` with
// `google.rpc.Code.PERMISSION_DENIED` if the IAM check fails or the `parent`
// resource is not in a Cloud Organization.
// For all requests, returns a `google.rpc.Status` with
// `google.rpc.Code.INVALID_ARGUMENT` if the request is malformed.
service ResourceSettingsService {
  option (google.api.default_host) = "resourcesettings.googleapis.com";
  option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform";

  // Lists all the settings that are available on the Cloud resource `parent`.
  rpc ListSettings(ListSettingsRequest) returns (ListSettingsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=organizations/*}/settings"
      additional_bindings {
        get: "/v1/{parent=folders/*}/settings"
      }
      additional_bindings {
        get: "/v1/{parent=projects/*}/settings"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets a setting.
  //
  // Returns a `google.rpc.Status` with `google.rpc.Code.NOT_FOUND` if the
  // setting does not exist.
  rpc GetSetting(GetSettingRequest) returns (Setting) {
    option (google.api.http) = {
      get: "/v1/{name=organizations/*/settings/*}"
      additional_bindings {
        get: "/v1/{name=folders/*/settings/*}"
      }
      additional_bindings {
        get: "/v1/{name=projects/*/settings/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Updates a setting.
  //
  // Returns a `google.rpc.Status` with `google.rpc.Code.NOT_FOUND` if the
  // setting does not exist.
  // Returns a `google.rpc.Status` with `google.rpc.Code.FAILED_PRECONDITION` if
  // the setting is flagged as read only.
  // Returns a `google.rpc.Status` with `google.rpc.Code.ABORTED` if the etag
  // supplied in the request does not match the persisted etag of the setting
  // value.
  //
  // On success, the response will contain only `name`, `local_value` and
  // `etag`.  The `metadata` and `effective_value` cannot be updated through
  // this API.
  //
  // Note: the supplied setting will perform a full overwrite of the
  // `local_value` field.
  rpc UpdateSetting(UpdateSettingRequest) returns (Setting) {
    option (google.api.http) = {
      patch: "/v1/{setting.name=organizations/*/settings/*}"
      body: "setting"
      additional_bindings {
        patch: "/v1/{setting.name=folders/*/settings/*}"
        body: "setting"
      }
      additional_bindings {
        patch: "/v1/{setting.name=projects/*/settings/*}"
        body: "setting"
      }
    };
  }
}

// The schema for settings.
message Setting {
  option (google.api.resource) = {
    type: "resourcesettings.googleapis.com/Setting"
    pattern: "projects/{project_number}/settings/{setting_name}"
    pattern: "folders/{folder}/settings/{setting_name}"
    pattern: "organizations/{organization}/settings/{setting_name}"
  };

  // The resource name of the setting. Must be in one of the following forms:
  //
  // * `projects/{project_number}/settings/{setting_name}`
  // * `folders/{folder_id}/settings/{setting_name}`
  // * `organizations/{organization_id}/settings/{setting_name}`
  //
  // For example, "/projects/123/settings/gcp-enableMyFeature"
  string name = 1;

  // Output only. Metadata about a setting which is not editable by the end user.
  SettingMetadata metadata = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The configured value of the setting at the given parent resource (ignoring
  // the resource hierarchy). The data type of [Value][google.cloud.resourcesettings.v1.Value] must always be
  // consistent with the data type defined in [Setting.metadata][google.cloud.resourcesettings.v1.Setting.metadata].
  Value local_value = 8;

  // Output only. The computed effective value of the setting at the given parent resource
  // (based on the resource hierarchy).
  //
  // The effective value evaluates to one of the following options in the given
  // order (the next option is used if the previous one does not exist):
  //
  // 1. the local setting value on the given resource: [Setting.local_value][google.cloud.resourcesettings.v1.Setting.local_value]
  // 2. if one of the given resource's ancestors have a local setting value,
  //    the local value at the nearest such ancestor
  // 3. the setting's default value: [SettingMetadata.default_value][google.cloud.resourcesettings.v1.SettingMetadata.default_value]
  // 4. an empty value (defined as a `Value` with all fields unset)
  //
  // The data type of [Value][google.cloud.resourcesettings.v1.Value] must always be
  // consistent with the data type defined in [Setting.metadata][google.cloud.resourcesettings.v1.Setting.metadata].
  Value effective_value = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // A fingerprint used for optimistic concurrency. See
  // [UpdateSetting][google.cloud.resourcesettings.v1.ResourceSettingsService.UpdateSetting] for more
  // details.
  string etag = 10;
}

// Metadata about a setting which is not editable by the end user.
message SettingMetadata {
  // The data type for setting values of this setting. See [Value][google.cloud.resourcesettings.v1.Value] for more
  // details on the available data types.
  enum DataType {
    // Unspecified data type.
    DATA_TYPE_UNSPECIFIED = 0;

    // A boolean setting.
    BOOLEAN = 1;

    // A string setting.
    STRING = 2;

    // A string set setting.
    STRING_SET = 3;

    // A Enum setting
    ENUM_VALUE = 4;
  }

  // The human readable name for this setting.
  string display_name = 1;

  // A detailed description of what this setting does.
  string description = 2;

  // A flag indicating that values of this setting cannot be modified (see
  // documentation of the specific setting for updates and reasons).
  bool read_only = 3;

  // The data type for this setting.
  DataType data_type = 4;

  // The value provided by [Setting.effective_value][google.cloud.resourcesettings.v1.Setting.effective_value] if no setting value is
  // explicitly set.
  //
  // Note: not all settings have a default value.
  Value default_value = 5;
}

// The data in a setting value.
message Value {
  // A string set value that can hold a set of strings. The maximum length of
  // each string is 200 characters and there can be a maximum of 50 strings in
  // the string set.
  message StringSet {
    // The strings in the set
    repeated string values = 1;
  }

  // A enum value that can hold any enum type setting values.
  // Each enum type is represented by a number, this representation
  // is stored in the definitions.
  message EnumValue {
    // The value of this enum
    string value = 1;
  }

  // Selects the data type and associated value.
  oneof value {
    // Defines this value as being a boolean value.
    bool boolean_value = 1;

    // Defines this value as being a string value.
    string string_value = 2;

    // Defines this value as being a StringSet.
    StringSet string_set_value = 3;

    // Defines this value as being a Enum.
    EnumValue enum_value = 4;
  }
}

// The request for ListSettings.
message ListSettingsRequest {
  // Required. The Cloud resource that parents the setting. Must be in one of the
  // following forms:
  //
  // * `projects/{project_number}`
  // * `projects/{project_id}`
  // * `folders/{folder_id}`
  // * `organizations/{organization_id}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "*"
    }
  ];

  // Unused. The size of the page to be returned.
  int32 page_size = 2;

  // Unused. A page token used to retrieve the next page.
  string page_token = 3;

  // The SettingView for this request.
  SettingView view = 4;
}

// The response from ListSettings.
message ListSettingsResponse {
  // A list of settings that are available at the specified Cloud resource.
  repeated Setting settings = 1;

  // Unused. A page token used to retrieve the next page.
  string next_page_token = 2;
}

// The request for GetSetting.
message GetSettingRequest {
  // Required. The name of the setting to get. See [Setting][google.cloud.resourcesettings.v1.Setting] for naming
  // requirements.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "resourcesettings.googleapis.com/Setting"
    }
  ];

  // The SettingView for this request.
  SettingView view = 2;
}

// The request for UpdateSetting.
message UpdateSettingRequest {
  // Required. The setting to update. See [Setting][google.cloud.resourcesettings.v1.Setting] for field requirements.
  Setting setting = 1 [(google.api.field_behavior) = REQUIRED];
}

// View options for Settings.
enum SettingView {
  // The default / unset value.
  // The API will default to the SETTING_VIEW_BASIC view.
  SETTING_VIEW_UNSPECIFIED = 0;

  // Include [Setting.metadata][google.cloud.resourcesettings.v1.Setting.metadata], but nothing else.
  // This is the default value (for both ListSettings and GetSetting).
  SETTING_VIEW_BASIC = 1;

  // Include [Setting.effective_value][google.cloud.resourcesettings.v1.Setting.effective_value], but nothing else.
  SETTING_VIEW_EFFECTIVE_VALUE = 2;

  // Include [Setting.local_value][google.cloud.resourcesettings.v1.Setting.local_value], but nothing else.
  SETTING_VIEW_LOCAL_VALUE = 3;
}
