// 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.resourcemanager.v3;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/iam/v1/iam_policy.proto";
import "google/iam/v1/policy.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.ResourceManager.V3";
option go_package = "cloud.google.com/go/resourcemanager/apiv3/resourcemanagerpb;resourcemanagerpb";
option java_multiple_files = true;
option java_outer_classname = "TagKeysProto";
option java_package = "com.google.cloud.resourcemanager.v3";
option php_namespace = "Google\\Cloud\\ResourceManager\\V3";
option ruby_package = "Google::Cloud::ResourceManager::V3";

// Allow users to create and manage tag keys.
service TagKeys {
  option (google.api.default_host) = "cloudresourcemanager.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform,"
      "https://www.googleapis.com/auth/cloud-platform.read-only";

  // Lists all TagKeys for a parent resource.
  rpc ListTagKeys(ListTagKeysRequest) returns (ListTagKeysResponse) {
    option (google.api.http) = {
      get: "/v3/tagKeys"
    };
    option (google.api.method_signature) = "parent";
  }

  // Retrieves a TagKey. This method will return `PERMISSION_DENIED` if the
  // key does not exist or the user does not have permission to view it.
  rpc GetTagKey(GetTagKeyRequest) returns (TagKey) {
    option (google.api.http) = {
      get: "/v3/{name=tagKeys/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Retrieves a TagKey by its namespaced name.
  // This method will return `PERMISSION_DENIED` if the key does not exist
  // or the user does not have permission to view it.
  rpc GetNamespacedTagKey(GetNamespacedTagKeyRequest) returns (TagKey) {
    option (google.api.http) = {
      get: "/v3/tagKeys/namespaced"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a new TagKey. If another request with the same parameters is
  // sent while the original request is in process, the second request
  // will receive an error. A maximum of 1000 TagKeys can exist under a parent
  // at any given time.
  rpc CreateTagKey(CreateTagKeyRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v3/tagKeys"
      body: "tag_key"
    };
    option (google.api.method_signature) = "tag_key";
    option (google.longrunning.operation_info) = {
      response_type: "TagKey"
      metadata_type: "CreateTagKeyMetadata"
    };
  }

  // Updates the attributes of the TagKey resource.
  rpc UpdateTagKey(UpdateTagKeyRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      patch: "/v3/{tag_key.name=tagKeys/*}"
      body: "tag_key"
    };
    option (google.api.method_signature) = "tag_key,update_mask";
    option (google.longrunning.operation_info) = {
      response_type: "TagKey"
      metadata_type: "UpdateTagKeyMetadata"
    };
  }

  // Deletes a TagKey. The TagKey cannot be deleted if it has any child
  // TagValues.
  rpc DeleteTagKey(DeleteTagKeyRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v3/{name=tagKeys/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "TagKey"
      metadata_type: "DeleteTagKeyMetadata"
    };
  }

  // Gets the access control policy for a TagKey. The returned policy may be
  // empty if no such policy or resource exists. The `resource` field should
  // be the TagKey's resource name. For example, "tagKeys/1234".
  // The caller must have
  // `cloudresourcemanager.googleapis.com/tagKeys.getIamPolicy` permission on
  // the specified TagKey.
  rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest)
      returns (google.iam.v1.Policy) {
    option (google.api.http) = {
      post: "/v3/{resource=tagKeys/*}:getIamPolicy"
      body: "*"
    };
    option (google.api.method_signature) = "resource";
  }

  // Sets the access control policy on a TagKey, replacing any existing
  // policy. The `resource` field should be the TagKey's resource name.
  // For example, "tagKeys/1234".
  // The caller must have `resourcemanager.tagKeys.setIamPolicy` permission
  // on the identified tagValue.
  rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest)
      returns (google.iam.v1.Policy) {
    option (google.api.http) = {
      post: "/v3/{resource=tagKeys/*}:setIamPolicy"
      body: "*"
    };
    option (google.api.method_signature) = "resource,policy";
  }

  // Returns permissions that a caller has on the specified TagKey.
  // The `resource` field should be the TagKey's resource name.
  // For example, "tagKeys/1234".
  //
  // There are no permissions required for making this API call.
  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest)
      returns (google.iam.v1.TestIamPermissionsResponse) {
    option (google.api.http) = {
      post: "/v3/{resource=tagKeys/*}:testIamPermissions"
      body: "*"
    };
    option (google.api.method_signature) = "resource,permissions";
  }
}

// A TagKey, used to group a set of TagValues.
message TagKey {
  option (google.api.resource) = {
    type: "cloudresourcemanager.googleapis.com/TagKey"
    pattern: "tagKeys/{tag_key}"
    style: DECLARATIVE_FRIENDLY
  };

  // Immutable. The resource name for a TagKey. Must be in the format
  // `tagKeys/{tag_key_id}`, where `tag_key_id` is the generated numeric id for
  // the TagKey.
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Immutable. The resource name of the TagKey's parent. A TagKey can be
  // parented by an Organization or a Project. For a TagKey parented by an
  // Organization, its parent must be in the form `organizations/{org_id}`. For
  // a TagKey parented by a Project, its parent can be in the form
  // `projects/{project_id}` or `projects/{project_number}`.
  string parent = 2 [(google.api.field_behavior) = IMMUTABLE];

  // Required. Immutable. The user friendly name for a TagKey. The short name
  // should be unique for TagKeys within the same tag namespace.
  //
  // The short name must be 1-63 characters, beginning and ending with
  // an alphanumeric character ([a-z0-9A-Z]) with dashes (-), underscores (_),
  // dots (.), and alphanumerics between.
  string short_name = 3 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Output only. Immutable. Namespaced name of the TagKey.
  string namespaced_name = 4 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Optional. User-assigned description of the TagKey. Must not exceed 256
  // characters.
  //
  // Read-write.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Output only. Creation time.
  google.protobuf.Timestamp create_time = 6
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Update time.
  google.protobuf.Timestamp update_time = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Entity tag which users can pass to prevent race conditions. This
  // field is always set in server responses. See UpdateTagKeyRequest for
  // details.
  string etag = 8 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A purpose denotes that this Tag is intended for use in policies
  // of a specific policy engine, and will involve that policy engine in
  // management operations involving this Tag. A purpose does not grant a
  // policy engine exclusive rights to the Tag, and it may be referenced by
  // other policy engines.
  //
  // A purpose cannot be changed once set.
  Purpose purpose = 11 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Purpose data corresponds to the policy system that the tag is
  // intended for. See documentation for `Purpose` for formatting of this field.
  //
  // Purpose data cannot be changed once set.
  map<string, string> purpose_data = 12
      [(google.api.field_behavior) = OPTIONAL];
}

// The request message for listing all TagKeys under a parent resource.
message ListTagKeysRequest {
  // Required. The resource name of the TagKey's parent.
  // Must be of the form `organizations/{org_id}` or `projects/{project_id}` or
  // `projects/{project_number}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { child_type: "*" }
  ];

  // Optional. The maximum number of TagKeys to return in the response. The
  // server allows a maximum of 300 TagKeys to return. If unspecified, the
  // server will use 100 as the default.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A pagination token returned from a previous call to `ListTagKey`
  // that indicates where this listing should continue from.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// The ListTagKeys response message.
message ListTagKeysResponse {
  // List of TagKeys that live under the specified parent in the request.
  repeated TagKey tag_keys = 1;

  // A pagination token returned from a previous call to `ListTagKeys`
  // that indicates from where listing should continue.
  string next_page_token = 2;
}

// The request message for getting a TagKey.
message GetTagKeyRequest {
  // Required. A resource name in the format `tagKeys/{id}`, such as
  // `tagKeys/123`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "cloudresourcemanager.googleapis.com/TagKey"
    }
  ];
}

// The request message for getting a TagKey by its namespaced name.
message GetNamespacedTagKeyRequest {
  // Required. A namespaced tag key name in the format
  // `{parentId}/{tagKeyShort}`, such as `42/foo` for a key with short name
  // "foo" under the organization with ID 42 or `r2-d2/bar` for a key with short
  // name "bar" under the project `r2-d2`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "cloudresourcemanager.googleapis.com/TagKey"
    }
  ];
}

// The request message for creating a TagKey.
message CreateTagKeyRequest {
  // Required. The TagKey to be created. Only fields `short_name`,
  // `description`, and `parent` are considered during the creation request.
  TagKey tag_key = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. Set to true to perform validations necessary for creating the
  // resource, but not actually perform the action.
  bool validate_only = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Runtime operation information for creating a TagKey.
message CreateTagKeyMetadata {}

// The request message for updating a TagKey.
message UpdateTagKeyRequest {
  // Required. The new definition of the TagKey. Only the `description` and
  // `etag` fields can be updated by this request. If the `etag` field is not
  // empty, it must match the `etag` field of the existing tag key. Otherwise,
  // `ABORTED` will be returned.
  TagKey tag_key = 1 [(google.api.field_behavior) = REQUIRED];

  // Fields to be updated. The mask may only contain `description` or
  // `etag`. If omitted entirely, both `description` and `etag` are assumed to
  // be significant.
  google.protobuf.FieldMask update_mask = 2;

  // Set as true to perform validations necessary for updating the resource, but
  // not actually perform the action.
  bool validate_only = 3;
}

// Runtime operation information for updating a TagKey.
message UpdateTagKeyMetadata {}

// The request message for deleting a TagKey.
message DeleteTagKeyRequest {
  // Required. The resource name of a TagKey to be deleted in the format
  // `tagKeys/123`. The TagKey cannot be a parent of any existing TagValues or
  // it will not be deleted successfully.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "cloudresourcemanager.googleapis.com/TagKey"
    }
  ];

  // Optional. Set as true to perform validations necessary for deletion, but
  // not actually perform the action.
  bool validate_only = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The etag known to the client for the expected state of the
  // TagKey. This is to be used for optimistic concurrency.
  string etag = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Runtime operation information for deleting a TagKey.
message DeleteTagKeyMetadata {}

// A purpose for each policy engine requiring such an integration. A single
// policy engine may have multiple purposes defined, however a TagKey may only
// specify a single purpose.
enum Purpose {
  // Unspecified purpose.
  PURPOSE_UNSPECIFIED = 0;

  // Purpose for Compute Engine firewalls.
  // A corresponding `purpose_data` should be set for the network the tag is
  // intended for. The key should be `network` and the value should be in
  // either of these two formats:
  //
  // -
  // `https://www.googleapis.com/compute/{compute_version}/projects/{project_id}/global/networks/{network_id}`
  // - `{project_id}/{network_name}`
  //
  // Examples:
  //
  // -
  // `https://www.googleapis.com/compute/staging_v1/projects/fail-closed-load-testing/global/networks/6992953698831725600`
  // - `fail-closed-load-testing/load-testing-network`
  GCE_FIREWALL = 1;
}
