// 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.shopping.merchant.accounts.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";

option csharp_namespace = "Google.Shopping.Merchant.Accounts.V1";
option go_package = "cloud.google.com/go/shopping/merchant/accounts/apiv1/accountspb;accountspb";
option java_multiple_files = true;
option java_outer_classname = "AccountServicesProto";
option java_package = "com.google.shopping.merchant.accounts.v1";
option php_namespace = "Google\\Shopping\\Merchant\\Accounts\\V1";
option ruby_package = "Google::Shopping::Merchant::Accounts::V1";

// Service to support AccountService API.
service AccountServicesService {
  option (google.api.default_host) = "merchantapi.googleapis.com";
  option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/content";

  // Retrieve an account service.
  rpc GetAccountService(GetAccountServiceRequest) returns (AccountService) {
    option (google.api.http) = {
      get: "/accounts/v1/{name=accounts/*/services/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // List account services for the specified accounts. Supports filtering.
  rpc ListAccountServices(ListAccountServicesRequest)
      returns (ListAccountServicesResponse) {
    option (google.api.http) = {
      get: "/accounts/v1/{parent=accounts/*}/services"
    };
    option (google.api.method_signature) = "parent";
  }

  // Propose an account service.
  rpc ProposeAccountService(ProposeAccountServiceRequest)
      returns (AccountService) {
    option (google.api.http) = {
      post: "/accounts/v1/{parent=accounts/*}/services:propose"
      body: "*"
    };
    option (google.api.method_signature) = "parent,provider,account_service";
  }

  // Approve an account service proposal.
  rpc ApproveAccountService(ApproveAccountServiceRequest)
      returns (AccountService) {
    option (google.api.http) = {
      post: "/accounts/v1/{name=accounts/*/services/*}:approve"
      body: "*"
    };
    option (google.api.method_signature) = "name";
  }

  // Reject an account service (both proposed and approve services can be
  // rejected).
  rpc RejectAccountService(RejectAccountServiceRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      post: "/accounts/v1/{name=accounts/*/services/*}:reject"
      body: "*"
    };
    option (google.api.method_signature) = "name";
  }
}

// The `AccountService` message represents a specific service that a provider
// account offers to a Merchant Center account.
//
// `AccountService` defines the permissions and capabilities granted to the
// provider, allowing for operations such as product management or campaign
// management.
//
// The lifecycle of an `AccountService` involves a proposal phase, where one
// party suggests the service, and an approval phase, where the other party
// accepts or rejects it. This handshake mechanism ensures mutual consent before
// any access is granted. This mechanism safeguards both parties by ensuring
// that access rights are granted appropriately and that both the business and
// provider are aware of the services enabled. In scenarios where a user is an
// admin of both accounts, the approval can happen automatically.
//
// The mutability of a service is also managed through `AccountService`. Some
// services might be immutable, for example, if they were established through
// other systems or APIs, and you cannot alter them through this API.
message AccountService {
  option (google.api.resource) = {
    type: "merchantapi.googleapis.com/AccountService"
    pattern: "accounts/{account}/services/{service}"
    plural: "accountServices"
    singular: "accountService"
  };

  // The list of mutability option settings a service can have.
  enum Mutability {
    // Unused default value
    MUTABILITY_UNSPECIFIED = 0;

    // The service can be mutated without restrictions.
    MUTABLE = 1;

    // The service is read-only and must not be mutated.
    IMMUTABLE = 2;
  }

  // The payload specified has to correspond to the `service_type`.
  oneof service_type {
    // Service type for managing products. This allows the provider to handle
    // product data on behalf of the business, including reading and writing
    // product listings. It's commonly used when the provider offers inventory
    // management or catalog synchronization services to keep the business's
    // product information up-to-date across platforms.
    ProductsManagement products_management = 100;

    // Service type for managing advertising campaigns. Grants the provider
    // access to create and manage the business's ad campaigns, including
    // setting up campaigns, adjusting bids, and optimizing performance.
    CampaignsManagement campaigns_management = 101;

    // Service type for account management. Enables the provider to perform
    // administrative actions on the business's account, such as
    // configuring account settings, managing users, or updating business
    // information.
    AccountManagement account_management = 102;

    // Service type for account aggregation. This enables the provider, which is
    // an advanced account, to manage multiple sub-accounts (client
    // accounts). Through this service, the advanced account provider can
    // perform administrative and operational tasks across all linked
    // sub-accounts.
    //
    // This is useful for agencies, aggregators, or large retailers that need
    // centralized control over many Merchant Center accounts.
    AccountAggregation account_aggregation = 103;

    // Service type for local listings management. The business group associated
    // with the external account id will be used to provide local inventory to
    // this Merchant Center account.
    LocalListingManagement local_listing_management = 104;

    // Service type for comparison shopping. The provider is a CSS (Comparison
    // Shopping Service) managing the account. See
    // https://support.google.com/merchants/answer/12653197
    ComparisonShopping comparison_shopping = 105;
  }

  // Identifier. The resource name of the account service.
  // Format: `accounts/{account}/services/{service}`
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Output only. The provider of the service. Either the reference to an
  // account such as `providers/123` or a well-known service provider (one of
  // `providers/GOOGLE_ADS` or `providers/GOOGLE_BUSINESS_PROFILE`).
  optional string provider = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The human-readable display name of the provider account.
  string provider_display_name = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Information about the state of the service in terms of
  // establishing it (e.g. is it pending approval or approved).
  Handshake handshake = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Whether the service is mutable (e.g. through Approve / Reject
  // RPCs). A service that was created through another system or API might be
  // immutable.
  Mutability mutability = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Immutable. An optional, immutable identifier that Google uses to refer to
  // this account when communicating with the provider. This should be the
  // unique account ID within the provider's system (for example, your shop ID
  // in Shopify).
  //
  // If you have multiple accounts with the same provider - for instance,
  // different accounts for various regions — the `external_account_id`
  // differentiates between them, ensuring accurate linking and integration
  // between Google and the provider.
  string external_account_id = 6 [(google.api.field_behavior) = IMMUTABLE];
}

// Request to get an account service.
message GetAccountServiceRequest {
  // Required. The resource name of the account service to get.
  // Format: `accounts/{account}/services/{service}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "merchantapi.googleapis.com/AccountService"
    }
  ];
}

// Request to list account services.
message ListAccountServicesRequest {
  // Required. The parent account of the account service to filter by.
  // Format: `accounts/{account}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "merchantapi.googleapis.com/Account"
    }
  ];

  // Optional. The token returned by the previous `list` request.
  string page_token = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The maximum number of elements to return in the response. Use for
  // paging. If no `page_size` is specified, `100` is used as the default value.
  // The maximum allowed value is `1000`.
  int32 page_size = 5 [(google.api.field_behavior) = OPTIONAL];
}

// Response after trying to list account services.
message ListAccountServicesResponse {
  // The account services that match your filter.
  repeated AccountService account_services = 1;

  // A page token. You can send the `page_token` to get the next page.
  // Only included in the `list` response if there are more pages.
  string next_page_token = 2;
}

// Request to propose an account service.
message ProposeAccountServiceRequest {
  // Required. The resource name of the parent account for the service.
  // Format: `accounts/{account}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "merchantapi.googleapis.com/Account"
    }
  ];

  // Required. The provider of the service. Either the reference to an account
  // such as `providers/123` or a well-known service provider (one of
  // `providers/GOOGLE_ADS` or `providers/GOOGLE_BUSINESS_PROFILE`).
  string provider = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The account service to propose.
  AccountService account_service = 4 [(google.api.field_behavior) = REQUIRED];
}

// Request to approve an account service.
message ApproveAccountServiceRequest {
  // Required. The resource name of the account service to approve.
  // Format: `accounts/{account}/services/{service}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "merchantapi.googleapis.com/AccountService"
    }
  ];
}

// Request to reject an account service.
message RejectAccountServiceRequest {
  // Required. The resource name of the account service to reject.
  // Format: `accounts/{account}/services/{service}`
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "merchantapi.googleapis.com/AccountService"
    }
  ];
}

// `ProductsManagement` payload.
message ProductsManagement {}

// `CampaignManagement` payload.
message CampaignsManagement {}

// `AccountManagement` payload.
message AccountManagement {}

// `AccountAggregation` payload.
message AccountAggregation {}

// `LocalListingManagement` payload.
message LocalListingManagement {}

// `ComparisonShopping` payload.
message ComparisonShopping {}

// The current status of establishing of the service.
// (for example, pending approval or approved).
message Handshake {
  // The approal state of a handshake.
  enum ApprovalState {
    // Unspecified approval status.
    APPROVAL_STATE_UNSPECIFIED = 0;

    // The service was proposed and is waiting to be confirmed.
    PENDING = 1;

    // Both parties have confirmed the service.
    ESTABLISHED = 2;

    // The service proposal was rejected.
    REJECTED = 3;
  }

  // The various actors that can be involved in a handshake.
  enum Actor {
    // Unspecified actor.
    ACTOR_UNSPECIFIED = 0;

    // The last change was done by the account who has this service.
    ACCOUNT = 1;

    // The last change was done by the other party who this service points to.
    OTHER_PARTY = 2;
  }

  // Output only. The approval state of this handshake.
  ApprovalState approval_state = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The most recent account to modify the account service's
  // `approval_status`.
  Actor actor = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
}
