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

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.ApiHub.V1";
option go_package = "cloud.google.com/go/apihub/apiv1/apihubpb;apihubpb";
option java_multiple_files = true;
option java_outer_classname = "CurateServiceProto";
option java_package = "com.google.cloud.apihub.v1";
option php_namespace = "Google\\Cloud\\ApiHub\\V1";
option ruby_package = "Google::Cloud::ApiHub::V1";

// This service is used for managing curations for processing API data consumed
// from collect layer.
service ApiHubCurate {
  option (google.api.default_host) = "apihub.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Create a curation resource in the API hub.
  // Once a curation resource is created, plugin instances can start using it.
  rpc CreateCuration(CreateCurationRequest) returns (Curation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/curations"
      body: "curation"
    };
    option (google.api.method_signature) = "parent,curation,curation_id";
  }

  // Get curation resource details.
  rpc GetCuration(GetCurationRequest) returns (Curation) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/curations/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // List curation resources in the API hub.
  rpc ListCurations(ListCurationsRequest) returns (ListCurationsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/curations"
    };
    option (google.api.method_signature) = "parent";
  }

  // Update a curation resource in the API hub. The following fields in the
  // [curation][google.cloud.apihub.v1.Curation] can be updated:
  //
  // * [display_name][google.cloud.apihub.v1.Curation.display_name]
  // * [description][google.cloud.apihub.v1.Curation.description]
  //
  // The
  // [update_mask][google.cloud.apihub.v1.UpdateApiRequest.update_mask]
  // should be used to specify the fields being updated.
  rpc UpdateCuration(UpdateCurationRequest) returns (Curation) {
    option (google.api.http) = {
      patch: "/v1/{curation.name=projects/*/locations/*/curations/*}"
      body: "curation"
    };
    option (google.api.method_signature) = "curation,update_mask";
  }

  // Delete a curation resource in the API hub. A curation can only be deleted
  // if it's not being used by any plugin instance.
  rpc DeleteCuration(DeleteCurationRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/curations/*}"
    };
    option (google.api.method_signature) = "name";
  }
}

// The [CreateCuration][ApiHub.CreateCuration] method's request.
message CreateCurationRequest {
  // Required. The parent resource for the curation resource.
  // Format: `projects/{project}/locations/{location}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "apihub.googleapis.com/Curation"
    }
  ];

  // Optional. The ID to use for the curation resource, which will become the
  // final component of the curations's resource name. This field is optional.
  //
  // * If provided, the same will be used. The service will throw an error if
  // the specified ID is already used by another curation resource in the API
  // hub.
  // * If not provided, a system generated ID will be used.
  //
  // This value should be 4-500 characters, and valid characters
  // are /[a-z][A-Z][0-9]-_/.
  string curation_id = 2 [(google.api.field_behavior) = OPTIONAL];

  // Required. The curation resource to create.
  Curation curation = 3 [(google.api.field_behavior) = REQUIRED];
}

// The [GetCuration][ApiHub.GetCuration] method's request.
message GetCurationRequest {
  // Required. The name of the curation resource to retrieve.
  // Format: `projects/{project}/locations/{location}/curations/{curation}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "apihub.googleapis.com/Curation" }
  ];
}

// The [UpdateCuration][ApiHub.UpdateCuration] method's request.
message UpdateCurationRequest {
  // Required. The curation resource to update.
  //
  // The curation resource's `name` field is used to identify the curation
  // resource to update.
  // Format: `projects/{project}/locations/{location}/curations/{curation}`
  Curation curation = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The list of fields to update.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = OPTIONAL];
}

// The [DeleteCuration][ApiHub.DeleteCuration] method's request.
message DeleteCurationRequest {
  // Required. The name of the curation resource to delete.
  // Format: `projects/{project}/locations/{location}/curations/{curation}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "apihub.googleapis.com/Curation" }
  ];
}

// The [ListCurations][ApiHub.ListCurations] method's request.
message ListCurationsRequest {
  // Required. The parent, which owns this collection of curation resources.
  // Format: `projects/{project}/locations/{location}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "apihub.googleapis.com/Curation"
    }
  ];

  // Optional. An expression that filters the list of curation resources.
  //
  // A filter expression consists of a field name, a comparison
  // operator, and a value for filtering. The value must be a string. The
  // comparison operator must be one of: `<`, `>`, `:` or `=`. Filters are case
  // insensitive.
  //
  // The following fields in the `curation resource` are eligible for filtering:
  //
  //   * `create_time` - The time at which the curation was created.
  //   The value should be in the (RFC3339)[https://tools.ietf.org/html/rfc3339]
  //   format. Allowed comparison operators: `>` and `<`.
  //   * `display_name` - The display name of the curation. Allowed
  //   comparison operators: `=`.
  //   * `state` - The state of the curation. Allowed comparison operators: `=`.
  //
  // Expressions are combined with either `AND` logic operator or `OR` logical
  // operator but not both of them together i.e. only one of the `AND` or `OR`
  // operator can be used throughout the filter string and both the operators
  // cannot be used together. No other logical operators are supported. At most
  // three filter fields are allowed in the filter string and if provided
  // more than that then `INVALID_ARGUMENT` error is returned by the API.
  //
  // Here are a few examples:
  //
  //   * `create_time < \"2021-08-15T14:50:00Z\" AND create_time >
  //   \"2021-08-10T12:00:00Z\"` -
  //   The curation resource was created before _2021-08-15 14:50:00 UTC_ and
  //   after _2021-08-10 12:00:00 UTC_.
  string filter = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The maximum number of curation resources to return. The service
  // may return fewer than this value. If unspecified, at most 50 curations will
  // be returned. The maximum value is 1000; values above 1000 will be coerced
  // to 1000.
  int32 page_size = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous `ListCurations` call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters (except page_size) provided to
  // `ListCurations` must match the call that provided the page token.
  string page_token = 4 [(google.api.field_behavior) = OPTIONAL];
}

// The [ListCurations][ApiHub.ListCurations] method's response.
message ListCurationsResponse {
  // The curation resources present in the API hub.
  repeated Curation curations = 1;

  // A token, which can be sent as `page_token` to retrieve the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 2;
}

// A curation resource in the API Hub.
message Curation {
  option (google.api.resource) = {
    type: "apihub.googleapis.com/Curation"
    pattern: "projects/{project}/locations/{location}/curations/{curation}"
    plural: "curations"
    singular: "curation"
  };

  // The plugin instance and associated action that is using the curation.
  message PluginInstanceActionID {
    // Output only. Plugin instance that is using the curation.
    // Format is
    // `projects/{project}/locations/{location}/plugins/{plugin}/instances/{instance}`
    string plugin_instance = 1 [
      (google.api.field_behavior) = OUTPUT_ONLY,
      (google.api.resource_reference) = {
        type: "apihub.googleapis.com/PluginInstance"
      }
    ];

    // Output only. The action ID that is using the curation.
    // This should map to one of the action IDs specified
    // in action configs in the plugin.
    string action_id = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // The state of the last execution of the curation.
  enum LastExecutionState {
    // Default unspecified state.
    LAST_EXECUTION_STATE_UNSPECIFIED = 0;

    // The last curation execution was successful.
    SUCCEEDED = 1;

    // The last curation execution failed.
    FAILED = 2;
  }

  // The error codes for failed executions.
  enum ErrorCode {
    // Default unspecified error code.
    ERROR_CODE_UNSPECIFIED = 0;

    // The execution failed due to an internal error.
    INTERNAL_ERROR = 1;

    // The curation is not authorized to trigger the endpoint uri.
    UNAUTHORIZED = 2;
  }

  // Identifier. The name of the curation.
  //
  // Format:
  // `projects/{project}/locations/{location}/curations/{curation}`
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Required. The display name of the curation.
  string display_name = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. The description of the curation.
  string description = 3 [(google.api.field_behavior) = OPTIONAL];

  // Required. The endpoint to be triggered for curation.
  Endpoint endpoint = 4 [(google.api.field_behavior) = REQUIRED];

  // Output only. The plugin instances and associated actions that are using the
  // curation. Note: A particular curation could be used by multiple plugin
  // instances or multiple actions in a plugin instance.
  repeated PluginInstanceActionID plugin_instance_actions = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The last execution state of the curation.
  LastExecutionState last_execution_state = 6
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The error code of the last execution of the curation. The
  // error code is populated only when the last execution state is failed.
  ErrorCode last_execution_error_code = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Error message describing the failure, if any, during the last
  // execution of the curation.
  string last_execution_error_message = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time at which the curation was created.
  google.protobuf.Timestamp create_time = 9
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time at which the curation was last updated.
  google.protobuf.Timestamp update_time = 10
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// The endpoint to be triggered for curation.
// The endpoint will be invoked with a request payload containing
// [ApiMetadata][google.cloud.apihub.v1.ApiHub.ApiMetadata].
// Response should contain curated data in the form of
// [ApiMetadata][google.cloud.apihub.v1.ApiHub.ApiMetadata].
message Endpoint {
  // The details of the endpoint to be triggered for curation.
  oneof endpoint_details {
    // Required. The details of the Application Integration endpoint to be
    // triggered for curation.
    ApplicationIntegrationEndpointDetails
        application_integration_endpoint_details = 1
        [(google.api.field_behavior) = REQUIRED];
  }
}

// The details of the Application Integration endpoint to be triggered for
// curation.
message ApplicationIntegrationEndpointDetails {
  // Required. The endpoint URI should be a valid REST URI for triggering an
  // Application Integration. Format:
  // `https://integrations.googleapis.com/v1/{name=projects/*/locations/*/integrations/*}:execute`
  // or
  // `https://{location}-integrations.googleapis.com/v1/{name=projects/*/locations/*/integrations/*}:execute`
  string uri = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The API trigger ID of the Application Integration workflow.
  string trigger_id = 2 [(google.api.field_behavior) = REQUIRED];
}
