// 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.retail.v2beta;

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

option csharp_namespace = "Google.Cloud.Retail.V2Beta";
option go_package = "cloud.google.com/go/retail/apiv2beta/retailpb;retailpb";
option java_multiple_files = true;
option java_outer_classname = "CatalogServiceProto";
option java_package = "com.google.cloud.retail.v2beta";
option objc_class_prefix = "RETAIL";
option php_namespace = "Google\\Cloud\\Retail\\V2beta";
option ruby_package = "Google::Cloud::Retail::V2beta";

// Service for managing catalog configuration.
service CatalogService {
  option (google.api.default_host) = "retail.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Lists all the [Catalog][google.cloud.retail.v2beta.Catalog]s associated
  // with the project.
  rpc ListCatalogs(ListCatalogsRequest) returns (ListCatalogsResponse) {
    option (google.api.http) = {
      get: "/v2beta/{parent=projects/*/locations/*}/catalogs"
    };
    option (google.api.method_signature) = "parent";
  }

  // Updates the [Catalog][google.cloud.retail.v2beta.Catalog]s.
  rpc UpdateCatalog(UpdateCatalogRequest) returns (Catalog) {
    option (google.api.http) = {
      patch: "/v2beta/{catalog.name=projects/*/locations/*/catalogs/*}"
      body: "catalog"
    };
    option (google.api.method_signature) = "catalog,update_mask";
  }

  // Set a specified branch id as default branch. API methods such as
  // [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search],
  // [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct],
  // [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]
  // will treat requests using "default_branch" to the actual branch id set as
  // default.
  //
  // For example, if `projects/*/locations/*/catalogs/*/branches/1` is set as
  // default, setting
  // [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] to
  // `projects/*/locations/*/catalogs/*/branches/default_branch` is equivalent
  // to setting
  // [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] to
  // `projects/*/locations/*/catalogs/*/branches/1`.
  //
  // Using multiple branches can be useful when developers would like
  // to have a staging branch to test and verify for future usage. When it
  // becomes ready, developers switch on the staging branch using this API
  // while keeping using
  // `projects/*/locations/*/catalogs/*/branches/default_branch` as
  // [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] to
  // route the traffic to this staging branch.
  //
  // CAUTION: If you have live predict/search traffic, switching the default
  // branch could potentially cause outages if the ID space of the new branch
  // is very different from the old one.
  //
  // More specifically:
  //
  // * PredictionService will only return product IDs from branch {newBranch}.
  // * SearchService will only return product IDs from branch {newBranch}
  //   (if branch is not explicitly set).
  // * UserEventService will only join events with products from branch
  //   {newBranch}.
  rpc SetDefaultBranch(SetDefaultBranchRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/v2beta/{catalog=projects/*/locations/*/catalogs/*}:setDefaultBranch"
      body: "*"
    };
    option (google.api.method_signature) = "catalog";
  }

  // Get which branch is currently default branch set by
  // [CatalogService.SetDefaultBranch][google.cloud.retail.v2beta.CatalogService.SetDefaultBranch]
  // method under a specified parent catalog.
  rpc GetDefaultBranch(GetDefaultBranchRequest)
      returns (GetDefaultBranchResponse) {
    option (google.api.http) = {
      get: "/v2beta/{catalog=projects/*/locations/*/catalogs/*}:getDefaultBranch"
    };
    option (google.api.method_signature) = "catalog";
  }

  // Gets a [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig].
  rpc GetCompletionConfig(GetCompletionConfigRequest)
      returns (CompletionConfig) {
    option (google.api.http) = {
      get: "/v2beta/{name=projects/*/locations/*/catalogs/*/completionConfig}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates the
  // [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig]s.
  rpc UpdateCompletionConfig(UpdateCompletionConfigRequest)
      returns (CompletionConfig) {
    option (google.api.http) = {
      patch: "/v2beta/{completion_config.name=projects/*/locations/*/catalogs/*/completionConfig}"
      body: "completion_config"
    };
    option (google.api.method_signature) = "completion_config,update_mask";
  }

  // Gets an [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig].
  rpc GetAttributesConfig(GetAttributesConfigRequest)
      returns (AttributesConfig) {
    option (google.api.http) = {
      get: "/v2beta/{name=projects/*/locations/*/catalogs/*/attributesConfig}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates the
  // [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig].
  //
  // The catalog attributes in the request will be updated in the catalog, or
  // inserted if they do not exist. Existing catalog attributes not included in
  // the request will remain unchanged. Attributes that are assigned to
  // products, but do not exist at the catalog level, are always included in the
  // response. The product attribute is assigned default values for missing
  // catalog attribute fields, e.g., searchable and dynamic facetable options.
  rpc UpdateAttributesConfig(UpdateAttributesConfigRequest)
      returns (AttributesConfig) {
    option (google.api.http) = {
      patch: "/v2beta/{attributes_config.name=projects/*/locations/*/catalogs/*/attributesConfig}"
      body: "attributes_config"
    };
    option (google.api.method_signature) = "attributes_config,update_mask";
  }

  // Adds the specified
  // [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] to the
  // [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig].
  //
  // If the [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] to
  // add already exists, an ALREADY_EXISTS error is returned.
  rpc AddCatalogAttribute(AddCatalogAttributeRequest)
      returns (AttributesConfig) {
    option (google.api.http) = {
      post: "/v2beta/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:addCatalogAttribute"
      body: "*"
    };
  }

  // Removes the specified
  // [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] from the
  // [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig].
  //
  // If the [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] to
  // remove does not exist, a NOT_FOUND error is returned.
  rpc RemoveCatalogAttribute(RemoveCatalogAttributeRequest)
      returns (AttributesConfig) {
    option (google.api.http) = {
      post: "/v2beta/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:removeCatalogAttribute"
      body: "*"
    };
  }

  // Removes all specified
  // [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]s from the
  // [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig].
  rpc BatchRemoveCatalogAttributes(BatchRemoveCatalogAttributesRequest)
      returns (BatchRemoveCatalogAttributesResponse) {
    option (google.api.http) = {
      post: "/v2beta/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:batchRemoveCatalogAttributes"
      body: "*"
    };
  }

  // Replaces the specified
  // [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] in the
  // [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig] by updating
  // the catalog attribute with the same
  // [CatalogAttribute.key][google.cloud.retail.v2beta.CatalogAttribute.key].
  //
  // If the [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] to
  // replace does not exist, a NOT_FOUND error is returned.
  rpc ReplaceCatalogAttribute(ReplaceCatalogAttributeRequest)
      returns (AttributesConfig) {
    option (google.api.http) = {
      post: "/v2beta/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:replaceCatalogAttribute"
      body: "*"
    };
  }
}

// Request for
// [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs]
// method.
message ListCatalogsRequest {
  // Required. The account resource name with an associated location.
  //
  // If the caller does not have permission to list
  // [Catalog][google.cloud.retail.v2beta.Catalog]s under this location,
  // regardless of whether or not this location exists, a PERMISSION_DENIED
  // error is returned.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Maximum number of [Catalog][google.cloud.retail.v2beta.Catalog]s to return.
  // If unspecified, defaults to 50. The maximum allowed value is 1000. Values
  // above 1000 will be coerced to 1000.
  //
  // If this field is negative, an INVALID_ARGUMENT is returned.
  int32 page_size = 2;

  // A page token
  // [ListCatalogsResponse.next_page_token][google.cloud.retail.v2beta.ListCatalogsResponse.next_page_token],
  // received from a previous
  // [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs]
  // call. Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to
  // [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs]
  // must match the call that provided the page token. Otherwise, an
  // INVALID_ARGUMENT error is returned.
  string page_token = 3;
}

// Response for
// [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs]
// method.
message ListCatalogsResponse {
  // All the customer's [Catalog][google.cloud.retail.v2beta.Catalog]s.
  repeated Catalog catalogs = 1;

  // A token that can be sent as
  // [ListCatalogsRequest.page_token][google.cloud.retail.v2beta.ListCatalogsRequest.page_token]
  // to retrieve the next page. If this field is omitted, there are no
  // subsequent pages.
  string next_page_token = 2;
}

// Request for
// [CatalogService.UpdateCatalog][google.cloud.retail.v2beta.CatalogService.UpdateCatalog]
// method.
message UpdateCatalogRequest {
  // Required. The [Catalog][google.cloud.retail.v2beta.Catalog] to update.
  //
  // If the caller does not have permission to update the
  // [Catalog][google.cloud.retail.v2beta.Catalog], regardless of whether or not
  // it exists, a PERMISSION_DENIED error is returned.
  //
  // If the [Catalog][google.cloud.retail.v2beta.Catalog] to update does not
  // exist, a NOT_FOUND error is returned.
  Catalog catalog = 1 [(google.api.field_behavior) = REQUIRED];

  // Indicates which fields in the provided
  // [Catalog][google.cloud.retail.v2beta.Catalog] to update.
  //
  // If an unsupported or unknown field is provided, an INVALID_ARGUMENT error
  // is returned.
  google.protobuf.FieldMask update_mask = 2;
}

// Request message to set a specified branch as new default_branch.
message SetDefaultBranchRequest {
  // Full resource name of the catalog, such as
  // `projects/*/locations/global/catalogs/default_catalog`.
  string catalog = 1 [
    (google.api.resource_reference) = { type: "retail.googleapis.com/Catalog" }
  ];

  // The final component of the resource name of a branch.
  //
  // This field must be one of "0", "1" or "2". Otherwise, an INVALID_ARGUMENT
  // error is returned.
  //
  // If there are no sufficient active products in the targeted branch and
  // [force][google.cloud.retail.v2beta.SetDefaultBranchRequest.force] is not
  // set, a FAILED_PRECONDITION error is returned.
  string branch_id = 2 [
    (google.api.resource_reference) = { type: "retail.googleapis.com/Branch" }
  ];

  // Some note on this request, this can be retrieved by
  // [CatalogService.GetDefaultBranch][google.cloud.retail.v2beta.CatalogService.GetDefaultBranch]
  // before next valid default branch set occurs.
  //
  // This field must be a UTF-8 encoded string with a length limit of 1,000
  // characters. Otherwise, an INVALID_ARGUMENT error is returned.
  string note = 3;

  // If set to true, it permits switching to a branch with
  // [branch_id][google.cloud.retail.v2beta.SetDefaultBranchRequest.branch_id]
  // even if it has no sufficient active products.
  bool force = 4;
}

// Request message to show which branch is currently the default branch.
message GetDefaultBranchRequest {
  // The parent catalog resource name, such as
  // `projects/*/locations/global/catalogs/default_catalog`.
  string catalog = 1 [
    (google.api.resource_reference) = { type: "retail.googleapis.com/Catalog" }
  ];
}

// Response message of
// [CatalogService.GetDefaultBranch][google.cloud.retail.v2beta.CatalogService.GetDefaultBranch].
message GetDefaultBranchResponse {
  // Full resource name of the branch id currently set as default branch.
  string branch = 1 [
    (google.api.resource_reference) = { type: "retail.googleapis.com/Branch" }
  ];

  // The time when this branch is set to default.
  google.protobuf.Timestamp set_time = 2;

  // This corresponds to
  // [SetDefaultBranchRequest.note][google.cloud.retail.v2beta.SetDefaultBranchRequest.note]
  // field, when this branch was set as default.
  string note = 3;
}

// Request for
// [CatalogService.GetCompletionConfig][google.cloud.retail.v2beta.CatalogService.GetCompletionConfig]
// method.
message GetCompletionConfigRequest {
  // Required. Full CompletionConfig resource name. Format:
  // `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "retail.googleapis.com/CompletionConfig"
    }
  ];
}

// Request for
// [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2beta.CatalogService.UpdateCompletionConfig]
// method.
message UpdateCompletionConfigRequest {
  // Required. The
  // [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig] to update.
  //
  // If the caller does not have permission to update the
  // [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig], then a
  // PERMISSION_DENIED error is returned.
  //
  // If the [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig] to
  // update does not exist, a NOT_FOUND error is returned.
  CompletionConfig completion_config = 1
      [(google.api.field_behavior) = REQUIRED];

  // Indicates which fields in the provided
  // [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig] to update.
  // The following are the only supported fields:
  //
  // * [CompletionConfig.matching_order][google.cloud.retail.v2beta.CompletionConfig.matching_order]
  // * [CompletionConfig.max_suggestions][google.cloud.retail.v2beta.CompletionConfig.max_suggestions]
  // * [CompletionConfig.min_prefix_length][google.cloud.retail.v2beta.CompletionConfig.min_prefix_length]
  // * [CompletionConfig.auto_learning][google.cloud.retail.v2beta.CompletionConfig.auto_learning]
  //
  // If not set, all supported fields are updated.
  google.protobuf.FieldMask update_mask = 2;
}

// Request for
// [CatalogService.GetAttributesConfig][google.cloud.retail.v2beta.CatalogService.GetAttributesConfig]
// method.
message GetAttributesConfigRequest {
  // Required. Full AttributesConfig resource name. Format:
  // `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "retail.googleapis.com/AttributesConfig"
    }
  ];
}

// Request for
// [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2beta.CatalogService.UpdateAttributesConfig]
// method.
message UpdateAttributesConfigRequest {
  // Required. The
  // [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig] to update.
  AttributesConfig attributes_config = 1
      [(google.api.field_behavior) = REQUIRED];

  // Indicates which fields in the provided
  // [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig] to update.
  // The following is the only supported field:
  //
  // * [AttributesConfig.catalog_attributes][google.cloud.retail.v2beta.AttributesConfig.catalog_attributes]
  //
  // If not set, all supported fields are updated.
  google.protobuf.FieldMask update_mask = 2;
}

// Request for
// [CatalogService.AddCatalogAttribute][google.cloud.retail.v2beta.CatalogService.AddCatalogAttribute]
// method.
message AddCatalogAttributeRequest {
  // Required. Full AttributesConfig resource name. Format:
  // `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`
  string attributes_config = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "retail.googleapis.com/AttributesConfig"
    }
  ];

  // Required. The
  // [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] to add.
  CatalogAttribute catalog_attribute = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Request for
// [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2beta.CatalogService.RemoveCatalogAttribute]
// method.
message RemoveCatalogAttributeRequest {
  // Required. Full AttributesConfig resource name. Format:
  // `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`
  string attributes_config = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "retail.googleapis.com/AttributesConfig"
    }
  ];

  // Required. The attribute name key of the
  // [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] to remove.
  string key = 2 [(google.api.field_behavior) = REQUIRED];
}

// Request for
// [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes]
// method.
message BatchRemoveCatalogAttributesRequest {
  // Required. The attributes config resource shared by all catalog attributes
  // being deleted. Format:
  // `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`
  string attributes_config = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "retail.googleapis.com/AttributesConfig"
    }
  ];

  // Required. The attribute name keys of the
  // [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]s to delete.
  // A maximum of 1000 catalog attributes can be deleted in a batch.
  repeated string attribute_keys = 2 [(google.api.field_behavior) = REQUIRED];
}

// Response of the
// [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes].
message BatchRemoveCatalogAttributesResponse {
  // Catalog attributes that were deleted. Only pre-loaded [catalog
  // attributes][google.cloud.retail.v2beta.CatalogAttribute] that are
  // neither [in
  // use][google.cloud.retail.v2beta.CatalogAttribute.in_use] by
  // products nor predefined can be deleted.
  repeated string deleted_catalog_attributes = 1;

  // Catalog attributes that were reset. [Catalog
  // attributes][google.cloud.retail.v2beta.CatalogAttribute] that are either
  // [in use][google.cloud.retail.v2beta.CatalogAttribute.in_use] by products or
  // are predefined attributes cannot be deleted; however, their configuration
  // properties will reset to default values upon removal request.
  repeated string reset_catalog_attributes = 2;
}

// Request for
// [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2beta.CatalogService.ReplaceCatalogAttribute]
// method.
message ReplaceCatalogAttributeRequest {
  // Required. Full AttributesConfig resource name. Format:
  // `projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`
  string attributes_config = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "retail.googleapis.com/AttributesConfig"
    }
  ];

  // Required. The updated
  // [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute].
  CatalogAttribute catalog_attribute = 2
      [(google.api.field_behavior) = REQUIRED];

  // Indicates which fields in the provided
  // [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] to update.
  // The following are NOT supported:
  //
  // * [CatalogAttribute.key][google.cloud.retail.v2beta.CatalogAttribute.key]
  //
  // If not set, all supported fields are updated.
  google.protobuf.FieldMask update_mask = 3;
}
