// Copyright 2026 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.dataplex.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/field_info.proto";
import "google/api/resource.proto";
import "google/cloud/dataplex/v1/business_glossary.proto";
import "google/cloud/dataplex/v1/catalog.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.Dataplex.V1";
option go_package = "cloud.google.com/go/dataplex/apiv1/dataplexpb;dataplexpb";
option java_multiple_files = true;
option java_outer_classname = "ApprovalWorkflowProto";
option java_package = "com.google.cloud.dataplex.v1";
option php_namespace = "Google\\Cloud\\Dataplex\\V1";
option ruby_package = "Google::Cloud::Dataplex::V1";

// Represents a proposed change to a metadata resource.
message ChangeRequest {
  option (google.api.resource) = {
    type: "dataplex.googleapis.com/ChangeRequest"
    pattern: "projects/{project}/locations/{location}/changeRequests/{change_request}"
    plural: "changeRequests"
    singular: "changeRequest"
  };

  // Possible states of a ChangeRequest.
  enum State {
    // State unspecified.
    STATE_UNSPECIFIED = 0;

    // The change is proposed and new.
    NEW = 1;

    // The change has been approved.
    APPROVED = 2;

    // The change has been rejected.
    REJECTED = 3;

    // The change request has expired.
    EXPIRED = 4;

    // The approved change has been revoked.
    REVOKED = 5;
  }

  // Enum representing the type of change in the payload.
  enum ChangeType {
    // State unspecified.
    CHANGE_TYPE_UNSPECIFIED = 0;

    // Request to create an Entry.
    CREATE_ENTRY = 1;

    // Request to update an Entry.
    UPDATE_ENTRY = 2;

    // Request to delete an Entry.
    DELETE_ENTRY = 3;

    // Request to create an EntryLink.
    CREATE_ENTRY_LINK = 4;

    // Request to delete an EntryLink.
    DELETE_ENTRY_LINK = 5;

    // Request to create a Glossary.
    CREATE_GLOSSARY = 7;

    // Request to update a Glossary.
    UPDATE_GLOSSARY = 8;

    // Request to delete a Glossary.
    DELETE_GLOSSARY = 9;

    // Request to create a GlossaryCategory.
    CREATE_GLOSSARY_CATEGORY = 10;

    // Request to update a GlossaryCategory.
    UPDATE_GLOSSARY_CATEGORY = 11;

    // Request to delete a GlossaryCategory.
    DELETE_GLOSSARY_CATEGORY = 13;

    // Request to create a GlossaryTerm.
    CREATE_GLOSSARY_TERM = 14;

    // Request to update a GlossaryTerm.
    UPDATE_GLOSSARY_TERM = 15;

    // Request to delete a GlossaryTerm.
    DELETE_GLOSSARY_TERM = 17;

    // Request to request Data Product access.
    REQUEST_DATA_PRODUCT_ACCESS = 33;
  }

  // Identifier. The relative resource name of the ChangeRequest, of the form:
  // projects/{project_number}/locations/{location_id}/changeRequests/{change_request_id}
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Output only. System generated globally unique ID for the ChangeRequest.
  string uid = 2 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OUTPUT_ONLY
  ];

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

  // Output only. The time when the ChangeRequest was last updated.
  google.protobuf.Timestamp update_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Justification of the ChangeRequest. This should explain
  // *why* the change is needed or why it should be approved.
  string justification = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. User-defined labels for the ChangeRequest.
  map<string, string> labels = 6 [(google.api.field_behavior) = OPTIONAL];

  // Output only. The email address of the user who created the ChangeRequest.
  string author = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The current state of the ChangeRequest.
  State state = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The full resource name of the target resource to be modified.
  // Example:
  // //dataplex.googleapis.com/projects/my-project/locations/us-central1/entryGroups/my-group/entries/my-entry
  string resource = 9 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = { type: "*" }
  ];

  // Detailed specification of the change, embedding the original request.
  oneof change_payload {
    // Payload for creating an Entry.
    CreateEntryRequest create_entry = 10;

    // Payload for updating an Entry.
    UpdateEntryRequest update_entry = 11;

    // Payload for deleting an Entry.
    DeleteEntryRequest delete_entry = 12;

    // Payload for creating an EntryLink.
    CreateEntryLinkRequest create_entry_link = 13;

    // Payload for deleting an EntryLink.
    DeleteEntryLinkRequest delete_entry_link = 14;

    // Payload for creating a Glossary.
    CreateGlossaryRequest create_glossary = 20;

    // Payload for updating a Glossary.
    UpdateGlossaryRequest update_glossary = 21;

    // Payload for deleting a Glossary.
    DeleteGlossaryRequest delete_glossary = 22;

    // Payload for creating a GlossaryCategory.
    CreateGlossaryCategoryRequest create_glossary_category = 23;

    // Payload for updating a GlossaryCategory.
    UpdateGlossaryCategoryRequest update_glossary_category = 24;

    // Payload for deleting a GlossaryCategory.
    DeleteGlossaryCategoryRequest delete_glossary_category = 26;

    // Payload for creating a GlossaryTerm.
    CreateGlossaryTermRequest create_glossary_term = 27;

    // Payload for updating a GlossaryTerm.
    UpdateGlossaryTermRequest update_glossary_term = 28;

    // Payload for deleting a GlossaryTerm.
    DeleteGlossaryTermRequest delete_glossary_term = 30;

    // Payload for Data Product access request.
    DataProductAccessRequest data_product_access_request = 32;
  }

  // Output only. The type of change represented by the change_payload.
  // This field is derived from the populated field in the change_payload oneof.
  ChangeType change_type = 19 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The reason provided for rejecting the ChangeRequest.
  string rejection_comment = 16 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The email address of the user who approved/rejected the
  // ChangeRequest.
  string approver = 17 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. This checksum is computed by the service. It can be sent on
  // update and delete requests to ensure the client has an up-to-date value
  // before proceeding.
  string etag = 18 [(google.api.field_behavior) = OPTIONAL];
}

// Message for requesting access to a Data Product. This will be used to
// create a ChangeRequest of type REQUEST_DATA_PRODUCT_ACCESS.
message DataProductAccessRequest {
  // Required. The resource name of the data product.
  // Format:
  // projects/{project_number}/locations/{location_id}/dataProducts/{data_product_id}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dataplex.googleapis.com/DataProduct"
    }
  ];

  // Required. The ID of the access group for which access is being requested.
  // This corresponds to the unique identifier of the AccessGroup defined in the
  // Data Product.
  string access_group_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Output only. The display name of the access group defined in the Data
  // Product for which access is being requested.
  string access_group_display_name = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. The principal for which access is being requested in IAM format.
  // If not specified, the requestor's principal will be used.
  // Example: `serviceAccount:my-sa@my-project.iam.gserviceaccount.com`.
  // Only service account principals are currently supported.
  // https://cloud.google.com/iam/docs/principal-identifiers
  optional string requested_principal = 3
      [(google.api.field_behavior) = OPTIONAL];
}
