// 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.shopping.merchant.products.v1beta;

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/shopping/merchant/products/v1beta/products_common.proto";
import "google/shopping/type/types.proto";

option go_package = "cloud.google.com/go/shopping/merchant/products/apiv1beta/productspb;productspb";
option java_multiple_files = true;
option java_outer_classname = "ProductInputsProto";
option java_package = "com.google.shopping.merchant.products.v1beta";

// Service to use ProductInput resource.
// This service works for products with online channel only.
service ProductInputsService {
  option (google.api.default_host) = "merchantapi.googleapis.com";
  option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/content";

  // Uploads a product input to your Merchant Center account. If an input
  // with the same contentLanguage, offerId, and dataSource already exists,
  // this method replaces that entry.
  //
  // After inserting, updating, or deleting a product input, it may take several
  // minutes before the processed product can be retrieved.
  rpc InsertProductInput(InsertProductInputRequest) returns (ProductInput) {
    option (google.api.http) = {
      post: "/products/v1beta/{parent=accounts/*}/productInputs:insert"
      body: "product_input"
    };
  }

  // Updates the existing product input in your Merchant Center account.
  //
  // After inserting, updating, or deleting a product input, it may take several
  // minutes before the processed product can be retrieved.
  rpc UpdateProductInput(UpdateProductInputRequest) returns (ProductInput) {
    option (google.api.http) = {
      patch: "/products/v1beta/{product_input.name=accounts/*/productInputs/*}"
      body: "product_input"
    };
    option (google.api.method_signature) = "product_input,update_mask";
  }

  // Deletes a product input from your Merchant Center account.
  //
  // After inserting, updating, or deleting a product input, it may take several
  // minutes before the processed product can be retrieved.
  rpc DeleteProductInput(DeleteProductInputRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/products/v1beta/{name=accounts/*/productInputs/*}"
    };
    option (google.api.method_signature) = "name";
  }
}

// This resource represents input data you submit for a product, not the
//  processed product that you see in Merchant Center, in Shopping ads, or
//  across Google surfaces. Product inputs, rules and supplemental data source
//  data are combined to create the processed
//  [Product][google.shopping.merchant.products.v1beta.Product].
//
//  Required product input attributes to pass data validation checks are
//  primarily defined in the [Products Data
//  Specification](https://support.google.com/merchants/answer/188494).
//
//  The following attributes are required:
//  [feedLabel][google.shopping.merchant.products.v1beta.Product.feed_label],
//  [contentLanguage][google.shopping.merchant.products.v1beta.Product.content_language]
//  and [offerId][google.shopping.merchant.products.v1beta.Product.offer_id].
//
//  After inserting, updating, or deleting a product input, it may take several
//  minutes before the processed product can be retrieved.
//
//  All fields in the product input and its sub-messages match the English name
//  of their corresponding attribute in the vertical spec with [some
//  exceptions](https://support.google.com/merchants/answer/7052112).
message ProductInput {
  option (google.api.resource) = {
    type: "merchantapi.googleapis.com/ProductInput"
    pattern: "accounts/{account}/productInputs/{productinput}"
    plural: "productInputs"
    singular: "productInput"
  };

  // Identifier. The name of the product input.
  // Format: accounts/{account}/productInputs/{productinput}
  // where the last section `productinput` consists of 4 parts:
  // channel~content_language~feed_label~offer_id
  // example for product input name is
  // "accounts/123/productInputs/online~en~US~sku123"
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Output only. The name of the processed product.
  // Format:
  // `"{product.name=accounts/{account}/products/{product}}"`
  string product = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Immutable. The
  // [channel](https://support.google.com/merchants/answer/7361332) of the
  // product.
  google.shopping.type.Channel.ChannelEnum channel = 3
      [(google.api.field_behavior) = IMMUTABLE];

  // Required. Immutable. Your unique identifier for the product. This is the
  // same for the product input and processed product. Leading and trailing
  // whitespaces are stripped and multiple whitespaces are replaced by a single
  // whitespace upon submission. See the [products data
  // specification](https://support.google.com/merchants/answer/188494#id) for
  // details.
  string offer_id = 4 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Required. Immutable. The two-letter [ISO
  // 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the
  // product.
  string content_language = 5 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Required. Immutable. The [feed
  // label](https://developers.google.com/shopping-content/guides/products/feed-labels)
  // for the product.
  string feed_label = 6 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Optional. Represents the existing version (freshness) of the product, which
  // can be used to preserve the right order when multiple updates are done at
  // the same time.
  //
  // If set, the insertion is prevented when version number is lower than
  // the current version number of the existing product. Re-insertion (for
  // example, product refresh after 30 days) can be performed with the current
  // `version_number`.
  //
  // Only supported for insertions into primary data sources.
  //
  // If the operation is prevented, the aborted exception will be
  // thrown.
  optional int64 version_number = 7 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A list of product attributes.
  Attributes attributes = 8 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A list of custom (merchant-provided) attributes. It can also be
  // used for submitting any attribute of the data specification in its generic
  // form (for example,
  // `{ "name": "size type", "value": "regular" }`).
  // This is useful for submitting attributes not explicitly exposed by the
  // API, such as additional attributes used for Buy on Google.
  // Maximum allowed number of characters for each
  // custom attribute is 10240 (represents sum of characters for name and
  // value). Maximum 2500 custom attributes can be set per product, with total
  // size of 102.4kB. Underscores in custom attribute names are replaced by
  // spaces upon insertion.
  repeated google.shopping.type.CustomAttribute custom_attributes = 9
      [(google.api.field_behavior) = OPTIONAL];
}

// Request message for the InsertProductInput method.
message InsertProductInputRequest {
  // Required. The account where this product will be inserted.
  // Format: accounts/{account}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "merchantapi.googleapis.com/Product"
    }
  ];

  // Required. The product input to insert.
  ProductInput product_input = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The primary or supplemental product data source name. If the
  // product already exists and data source provided is different, then the
  // product will be moved to a new data source.
  //
  // Only API data sources are supported.
  //
  // Format: `accounts/{account}/dataSources/{datasource}`.
  string data_source = 3 [(google.api.field_behavior) = REQUIRED];
}

// Request message for the UpdateProductInput method.
// The product (primary input) must exist for the update to succeed.
// If the update is for a primary product input, the existing primary product
// input must be from the same data source.
message UpdateProductInputRequest {
  // Required. The product input resource to update. Information you submit will
  // be applied to the processed product as well.
  ProductInput product_input = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The list of product attributes to be updated.
  //
  // If the update mask is omitted, then it is treated as implied field mask
  // equivalent to all fields that are populated (have a non-empty value).
  //
  // Attributes specified in the update mask without a value specified in the
  // body will be deleted from the product.
  //
  // Update mask can only be specified for top level fields in
  // attributes and custom attributes.
  //
  // To specify the update mask for custom attributes you need to add the
  // `custom_attribute.` prefix.
  //
  // Providing special "*" value for full product replacement is not supported.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = OPTIONAL];

  // Required. The primary or supplemental product data source where
  // `data_source` name identifies the product input to be updated.
  //
  // Only API data sources are supported.
  //
  // Format: `accounts/{account}/dataSources/{datasource}`.
  string data_source = 3 [(google.api.field_behavior) = REQUIRED];
}

// Request message for the DeleteProductInput method.
message DeleteProductInputRequest {
  // Required. The name of the product input resource to delete.
  // Format: accounts/{account}/productInputs/{product}
  // where the last section `product` consists of 4 parts:
  // channel~content_language~feed_label~offer_id
  // example for product name is
  // "accounts/123/productInputs/online~en~US~sku123"
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "merchantapi.googleapis.com/ProductInput"
    }
  ];

  // Required. The primary or supplemental data source from which the product
  // input should be deleted. Format:
  // `accounts/{account}/dataSources/{datasource}`.
  string data_source = 2 [(google.api.field_behavior) = REQUIRED];
}
