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

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

option go_package = "cloud.google.com/go/biglake/apiv1/biglakepb;biglakepb";
option java_multiple_files = true;
option java_outer_classname = "IcebergRestCatalogProto";
option java_package = "com.google.cloud.biglake.v1";
option (google.api.resource_definition) = {
  type: "biglake.googleapis.com/Table"
  pattern: "projects/{project}/catalogs/{catalog}/namespaces/{namespace}/tables/{table}"
};
option (google.api.resource_definition) = {
  type: "biglake.googleapis.com/Namespace"
  pattern: "projects/{project}/catalogs/{catalog}/namespaces/{namespace}"
};

// Iceberg Catalog Service API: this implements the open-source Iceberg REST
// Catalog API.
// See the API definition here:
// https://github.com/apache/iceberg/blob/main/open-api/rest-catalog-open-api.yaml
//
// The API is defined as OpenAPI 3.1.1 spec.
//
// Currently we only support the following methods:
// - GetConfig/GetIcebergCatalogConfig
// - ListIcebergNamespaces
// - CheckIcebergNamespaceExists
// - GetIcebergNamespace
// - CreateIcebergNamespace (only supports single level)
// - DeleteIcebergNamespace
// - UpdateIcebergNamespace properties
// - ListTableIdentifiers
// - CreateIcebergTable
// - DeleteIcebergTable
// - GetIcebergTable
// - UpdateIcebergTable (CommitTable)
// - LoadIcebergTableCredentials
// - RegisterTable
//
// Users are required to provided the `X-Goog-User-Project` header with the
// project id or number which can be different from the bucket project id.
// That project will be charged for the API calls and the calling user must have
// access to that project. The caller must have `serviceusage.services.use`
// permission on the project.
service IcebergCatalogService {
  option (google.api.default_host) = "biglake.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/bigquery,"
      "https://www.googleapis.com/auth/cloud-platform";

  // GetIcebergCatalogConfig lists all catalog configuration settings. Most
  // importantly it contains the optional `endpoints` field which lists what
  // methods this catalog supports, since we are not supporting all the methods
  // right now.
  // It returns all the methods defined in this service (subject to project
  // config allowlisting).
  //
  // This is not a GCP resource.
  rpc GetIcebergCatalogConfig(GetIcebergCatalogConfigRequest)
      returns (IcebergCatalogConfig) {
    option (google.api.http) = {
      get: "/iceberg/v1/restcatalog/v1/config"
    };
  }

  // Lists Iceberg namespaces in the catalog. We only support one level of
  // nesting for namespaces.
  rpc ListIcebergNamespaces(ListIcebergNamespacesRequest)
      returns (ListIcebergNamespacesResponse) {
    option (google.api.http) = {
      get: "/iceberg/v1/restcatalog/v1/{api_parent=projects/*/catalogs/*}/namespaces"
    };
    option (google.api.method_signature) = "api_parent";
  }

  // Returns 204 if the namespace exists, 404 otherwise.
  rpc CheckIcebergNamespaceExists(GetIcebergNamespaceRequest)
      returns (google.protobuf.Empty) {
    option (google.api.method_signature) = "name";
  }

  // Gets an Iceberg namespace in the catalog (or checks if it exists, if the
  // method is HEAD).
  rpc GetIcebergNamespace(GetIcebergNamespaceRequest)
      returns (IcebergNamespace) {
    option (google.api.http) = {
      get: "/iceberg/v1/restcatalog/v1/{name=projects/*/catalogs/*/namespaces/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a namespace in the catalog.
  rpc CreateIcebergNamespace(CreateIcebergNamespaceRequest)
      returns (IcebergNamespace) {
    option (google.api.http) = {
      post: "/iceberg/v1/restcatalog/v1/{parent=projects/*/catalogs/*}/namespaces"
      body: "iceberg_namespace"
    };
    option (google.api.method_signature) = "parent,iceberg_namespace";
  }

  // Returns 204, not 200 on success.
  rpc DeleteIcebergNamespace(DeleteIcebergNamespaceRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/iceberg/v1/restcatalog/v1/{name=projects/*/catalogs/*/namespaces/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates namespace properties.
  rpc UpdateIcebergNamespace(UpdateIcebergNamespaceRequest)
      returns (UpdateIcebergNamespaceResponse) {
    option (google.api.http) = {
      patch: "/iceberg/v1/restcatalog/v1/{name=projects/*/catalogs/*/namespaces/*}/properties"
      body: "iceberg_namespace_update"
      additional_bindings {
        post: "/iceberg/v1/restcatalog/v1/{name=projects/*/catalogs/*/namespaces/*}/properties"
        body: "iceberg_namespace_update"
      }
    };
  }

  // Lists table identifiers (not *tables*) in the namespace.
  rpc ListIcebergTableIdentifiers(ListIcebergTableIdentifiersRequest)
      returns (ListIcebergTableIdentifiersResponse) {
    option (google.api.http) = {
      get: "/iceberg/v1/restcatalog/v1/{parent=projects/*/catalogs/*/namespaces/*}/tables"
    };
    option (google.api.method_signature) = "parent";
  }

  // Creates a table in the namespace.
  rpc CreateIcebergTable(CreateIcebergTableRequest)
      returns (google.api.HttpBody) {
    option (google.api.http) = {
      post: "/iceberg/v1/restcatalog/v1/{parent=projects/*/catalogs/*/namespaces/*}/tables"
      body: "*"
    };
    option (google.api.method_signature) = "parent,http_body";
  }

  // Returns 204 if the table exists, 404 otherwise. This is a `HEAD` HTTP
  // method.
  rpc CheckIcebergTableExists(GetIcebergTableRequest)
      returns (google.protobuf.Empty) {
    option (google.api.method_signature) = "name";
  }

  // Deletes a table in the namespace.
  rpc DeleteIcebergTable(DeleteIcebergTableRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/iceberg/v1/restcatalog/v1/{name=projects/*/catalogs/*/namespaces/*/tables/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Gets a table in the namespace.
  rpc GetIcebergTable(GetIcebergTableRequest) returns (google.api.HttpBody) {
    option (google.api.http) = {
      get: "/iceberg/v1/restcatalog/v1/{name=projects/*/catalogs/*/namespaces/*/tables/*}"
    };
    option (google.api.method_signature) = "name,snapshots";
  }

  // Loads credentials for a table in the namespace.
  rpc LoadIcebergTableCredentials(GetIcebergTableRequest)
      returns (LoadIcebergTableCredentialsResponse) {
    option (google.api.http) = {
      get: "/iceberg/v1/restcatalog/v1/{name=projects/*/catalogs/*/namespaces/*/tables/*}/credentials"
    };
    option (google.api.method_signature) = "name";
  }

  // This is CommitTable Iceberg API, which maps to `UpdateIcebergTable` in the
  // Google API nomenclature.
  rpc UpdateIcebergTable(UpdateIcebergTableRequest)
      returns (google.api.HttpBody) {
    option (google.api.http) = {
      post: "/iceberg/v1/restcatalog/v1/{name=projects/*/catalogs/*/namespaces/*/tables/*}"
      body: "*"
    };
  }

  // Register a table using given metadata file location.
  rpc RegisterIcebergTable(RegisterIcebergTableRequest)
      returns (google.api.HttpBody) {
    option (google.api.http) = {
      post: "/iceberg/v1/restcatalog/v1/{parent=projects/*/catalogs/*/namespaces/*}/register"
      body: "*"
    };
  }

  // Returns the Iceberg REST Catalog configuration options.
  rpc GetIcebergCatalog(GetIcebergCatalogRequest) returns (IcebergCatalog) {
    option (google.api.http) = {
      get: "/iceberg/v1/restcatalog/extensions/{name=projects/*/catalogs/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists the Iceberg REST Catalogs.
  rpc ListIcebergCatalogs(ListIcebergCatalogsRequest)
      returns (ListIcebergCatalogsResponse) {
    option (google.api.http) = {
      get: "/iceberg/v1/restcatalog/extensions/{parent=projects/*}/catalogs"
    };
    option (google.api.method_signature) = "parent";
  }

  // Deletes the Iceberg REST Catalog.
  // Delete does not delete a catalog that has contents -- at least one
  // namespace.
  //
  // Delete is not supported for all catalog types.
  rpc DeleteIcebergCatalog(DeleteIcebergCatalogRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/iceberg/v1/restcatalog/extensions/{name=projects/*/catalogs/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Update the Iceberg REST Catalog configuration options.
  rpc UpdateIcebergCatalog(UpdateIcebergCatalogRequest)
      returns (IcebergCatalog) {
    option (google.api.http) = {
      patch: "/iceberg/v1/restcatalog/extensions/{iceberg_catalog.name=projects/*/catalogs/*}"
      body: "iceberg_catalog"
    };
    option (google.api.method_signature) = "iceberg_catalog,update_mask";
  }

  // Creates the Iceberg REST Catalog.
  // Currently only supports Google Cloud Storage Bucket catalogs.
  // Google Cloud Storage Bucket catalog id is the bucket for which the
  // catalog is created (e.g. `my-catalog` for `gs://my-catalog`).
  //
  // If the bucket does not exist, of the caller does not have bucket metadata
  // permissions, the catalog will not be created.
  rpc CreateIcebergCatalog(CreateIcebergCatalogRequest)
      returns (IcebergCatalog) {
    option (google.api.http) = {
      post: "/iceberg/v1/restcatalog/extensions/{parent=projects/*}/catalogs"
      body: "iceberg_catalog"
    };
    option (google.api.method_signature) =
        "parent,iceberg_catalog,iceberg_catalog_id";
  }

  // Failover the catalog to a new primary replica region.
  rpc FailoverIcebergCatalog(FailoverIcebergCatalogRequest)
      returns (FailoverIcebergCatalogResponse) {
    option (google.api.http) = {
      post: "/iceberg/v1/restcatalog/extensions/{name=projects/*/catalogs/*}:failover"
      body: "*"
    };
    option (google.api.method_signature) = "name,primary_replica";
  }
}

// The request message for the `RegisterIcebergTable` API.
message RegisterIcebergTableRequest {
  // Required. Table to register in the format:
  // `projects/{project_id}/catalogs/{catalog_id}/namespaces/{namespace}`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "biglake.googleapis.com/Namespace"
    }
  ];

  // Required. The name of the table to register.
  string name = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The metadata location of the table.
  string metadata_location = 3
      [json_name = "metadata-location", (google.api.field_behavior) = REQUIRED];

  // Optional. Whether to overwrite the table if it already exists. Default is
  // false. Currently this field is ignored and an error is returned if the
  // table already exists.
  string overwrite = 4 [(google.api.field_behavior) = OPTIONAL];
}

// The Iceberg REST Catalog information.
message IcebergCatalog {
  option (google.api.resource) = {
    type: "biglake.googleapis.com/Catalog"
    pattern: "projects/{project}/catalogs/{catalog}"
    plural: "catalogs"
    singular: "catalog"
  };

  // Determines the catalog type.
  enum CatalogType {
    // Default value. This value is unused.
    CATALOG_TYPE_UNSPECIFIED = 0;

    // Catalog type for Google Cloud Storage Buckets.
    CATALOG_TYPE_GCS_BUCKET = 1;
  }

  // The credential mode used for the catalog.
  enum CredentialMode {
    // Default value. This value is unused.
    CREDENTIAL_MODE_UNSPECIFIED = 0;

    // End user credentials, default. The authenticating user must have access
    // to the catalog resources and the corresponding Google Cloud Storage
    // files.
    CREDENTIAL_MODE_END_USER = 1;

    // Use credential vending. The authenticating user must have access to the
    // catalog resources and the system will provide the caller with downscoped
    // credentials to access the Google Cloud Storage files. All table
    // operations in this mode would require `X-Iceberg-Access-Delegation`
    // header with `vended-credentials` value included. System will generate a
    // service account and the catalog administrator must grant the service
    // account appropriate permissions.
    //
    // See:
    // https://github.com/apache/iceberg/blob/931865ecaf40a827f9081dddb675bf1c95c05461/open-api/rest-catalog-open-api.yaml#L1854
    // for more details.
    CREDENTIAL_MODE_VENDED_CREDENTIALS = 2;
  }

  // Identifier. The catalog name, `projects/my-project/catalogs/my-catalog`.
  // This field is immutable.
  // This field is ignored for CreateIcebergCatalog.
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Optional. The credential mode for the catalog.
  CredentialMode credential_mode = 2
      [json_name = "credential-mode", (google.api.field_behavior) = OPTIONAL];

  // Output only. The service account used for credential vending, output only.
  // Might be empty if Credential vending was never enabled for the catalog.
  string biglake_service_account = 3 [
    json_name = "biglake-service-account",
    (google.api.field_behavior) = OUTPUT_ONLY
  ];

  // Required. The catalog type. Required for CreateIcebergCatalog.
  CatalogType catalog_type = 4
      [json_name = "catalog-type", (google.api.field_behavior) = REQUIRED];

  // Optional. The default location for the catalog. For the Google Cloud
  // Storage Bucket catalog this is output only.
  string default_location = 5
      [json_name = "default-location", (google.api.field_behavior) = OPTIONAL];

  // Output only. The GCP region(s) where the catalog metadata is stored.
  // This will contain one value for all locations, except for the catalogs that
  // are configured to use custom dual region buckets.
  repeated string catalog_regions = 6 [
    json_name = "catalog-regions",
    (google.api.field_behavior) = OUTPUT_ONLY
  ];

  // Output only. When the catalog was created.
  google.protobuf.Timestamp create_time = 7
      [json_name = "create-time", (google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. When the catalog was last updated.
  google.protobuf.Timestamp update_time = 8
      [json_name = "update-time", (google.api.field_behavior) = OUTPUT_ONLY];
}

// The request message for the `CreateIcebergCatalog` API.
message CreateIcebergCatalogRequest {
  // Required. The parent resource where this catalog will be created.
  // Format: projects/{project_id}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "cloudresourcemanager.googleapis.com/Project"
    }
  ];

  // Required. The name of the catalog.
  string iceberg_catalog_id = 3 [
    json_name = "iceberg-catalog-id",
    (google.api.field_behavior) = REQUIRED
  ];

  // Required. The catalog to create.
  // The required fields for creation are:
  // - catalog_type.
  // Optionally: credential_mode can be provided, if Credential Vending is
  // desired.
  IcebergCatalog iceberg_catalog = 2 [(google.api.field_behavior) = REQUIRED];
}

// The request message for the `DeleteIcebergCatalog` API.
message DeleteIcebergCatalogRequest {
  // Required. The catalog to delete.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "biglake.googleapis.com/Catalog" }
  ];
}

// The request message for the `UpdateIcebergCatalog` API.
message UpdateIcebergCatalogRequest {
  // Required. The catalog to update.
  IcebergCatalog iceberg_catalog = 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 request message for the `GetIcebergCatalog` API.
message GetIcebergCatalogRequest {
  // Required. The catalog to get.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "biglake.googleapis.com/Catalog" }
  ];
}

// The request message for the `ListIcebergCatalogs` API.
message ListIcebergCatalogsRequest {
  // The enumeration of the views that can be returned.
  enum CatalogView {
    // Default/unset value. Same as BASIC.
    CATALOG_VIEW_UNSPECIFIED = 0;

    // Include only the name and catalog type.
    CATALOG_VIEW_BASIC = 1;

    // Include all fields of the catalog.
    CATALOG_VIEW_FULL = 2;
  }

  // Required. The parent resource where this catalog will be created.
  // Format: projects/{project_id}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "cloudresourcemanager.googleapis.com/Project"
    }
  ];

  // Optional. The view of the catalog to return.
  CatalogView view = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The maximum number of catalogs to return. The service may return
  // fewer than this value.
  int32 page_size = 3
      [json_name = "page-size", (google.api.field_behavior) = OPTIONAL];

  // Optional. The page token, received from a previous `ListIcebergCatalogs`
  // call. Provide this to retrieve the subsequent page.
  string page_token = 4
      [json_name = "page-token", (google.api.field_behavior) = OPTIONAL];
}

// The response message for the `ListIcebergCatalogs` API.
message ListIcebergCatalogsResponse {
  // Output only. The list of iceberg catalogs.
  repeated IcebergCatalog iceberg_catalogs = 1 [
    json_name = "iceberg-catalogs",
    (google.api.field_behavior) = OUTPUT_ONLY
  ];

  // Output only. The next page token for pagination.
  string next_page_token = 2 [
    json_name = "next-page-token",
    (google.api.field_behavior) = OUTPUT_ONLY
  ];

  // Output only. The list of unreachable cloud regions for router fanout.
  repeated string unreachable = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Request message for FailoverIcebergCatalog.
message FailoverIcebergCatalogRequest {
  // Required. The name of the catalog in the form
  // "projects/{project_id}/catalogs/{catalog_id}"
  string name = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The region being assigned as the new primary replica region. For
  // example "us-east1". This must be one of the replica regions in the
  // catalog's list of replicas marked as a "secondary".
  string primary_replica = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. If set, only validate the request, but do not perform the update.
  // This can be used to inspect the replication_time at any time, including
  // before performing a fail-over.
  bool validate_only = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. If unset, wait for all data from the source region to replicate
  // to the new primary region before completing the failover, with no data loss
  // (also called "soft failover"). If set, failover immediately, accepting the
  // loss of any data committed in the source region after this timestamp, that
  // has not yet replicated. If any data committed before this time has not
  // replicated, the failover will not be performed and an error will be
  // returned (also called "hard failover").
  google.protobuf.Timestamp conditional_failover_replication_time = 4
      [(google.api.field_behavior) = OPTIONAL];
}

// Response message for FailoverIcebergCatalog.
message FailoverIcebergCatalogResponse {
  // Output only. The min timestamp for which all namespaces and table metadata
  // have been replicated in the region specified as the new primary_replica.
  // Some resources may have been replicated more recently than this timestamp.
  // If empty, the replica has just been created and has not yet been fully
  // initialized. NOTE: When the Cloud Storage replication watermark is
  // available, this will represent both catalog metadata and Cloud Storage
  // data.
  google.protobuf.Timestamp replication_time = 1
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// The update message for the `UpdateIcebergTable` API.
message UpdateIcebergTableRequest {
  // Required. Table to commit in the format:
  // `projects/{project_id}/namespaces/{namespace}/tables/{table}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "biglake.googleapis.com/Table" }
  ];

  // Required. The request body that should be in the format of Apache Iceberg's
  // `#/components/schemas/CommitTableRequest`. Content type is expected to be
  // `application/json`. Added this field for easier json parsing.
  google.api.HttpBody http_body = 2
      [json_name = "updates", (google.api.field_behavior) = REQUIRED];
}

// The request message for the `GetIcebergTable` API.
message GetIcebergTableRequest {
  // Required. Table to get in the format:
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "biglake.googleapis.com/Table" }
  ];

  // Optional. What snapshot to get. Valid only for GetIcebergTable.
  string snapshots = 2 [(google.api.field_behavior) = OPTIONAL];
}

// The request message for the `DeleteIcebergTable` API.
message DeleteIcebergTableRequest {
  // Required. Table to delete in the format:
  // `projects/{project_id}/namespaces/{namespace}/tables/{table}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "biglake.googleapis.com/Table" }
  ];

  // Optional. If true we'll delete both the table and the data. Currently
  // purgin data is not supported.
  bool purge_requested = 2 [(google.api.field_behavior) = OPTIONAL];
}

// The request message for the `CreateIcebergTable` API.
message CreateIcebergTableRequest {
  // Required. The parent resource where this table will be created.
  // Format: projects/{project_id}/namespaces/{namespace}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "biglake.googleapis.com/Namespace"
    }
  ];

  // Required. The request body that should be in the format of Apache Iceberg's
  // `#/components/schemas/CreateTableRequest`. Content type is expected to be
  // `application/json`.
  google.api.HttpBody http_body = 3 [(google.api.field_behavior) = REQUIRED];
}

// The request message for the `ListIcebergTableIdentifiers` API.
message ListIcebergTableIdentifiersRequest {
  // Optional. PageToken for pagination.
  string page_token = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Page size for pagination.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Required. The namespace to list tables from.
  string parent = 3 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "biglake.googleapis.com/Namespace"
    }
  ];
}

// The table identifier.
message TableIdentifier {
  // The namespace of the table. This is always 1 element, since we don't
  // support nested namespaces.
  repeated string namespace = 1 [(google.api.resource_reference) = {
    type: "biglake.googleapis.com/Namespace"
  }];

  // The table name.
  string name = 2;
}

// The response message for the `ListIcebergTableIdentifiers` API.
message ListIcebergTableIdentifiersResponse {
  // Output only. The list of table identifiers.
  repeated TableIdentifier identifiers = 1
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The next page token for pagination.
  string next_page_token = 2 [
    json_name = "next-page-token",
    (google.api.field_behavior) = OUTPUT_ONLY
  ];
}

// The request message for the `UpdateIcebergNamespace` API.
message IcebergNamespaceUpdate {
  // Optional. Keys of the properties to remove.
  repeated string removals = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. List of properties to update or add.
  map<string, string> updates = 3 [(google.api.field_behavior) = OPTIONAL];
}

// The request message for the `UpdateIcebergNamespace` API.
message UpdateIcebergNamespaceRequest {
  // Required. The namespace to update.
  //
  // The namespace's `name` field is used to identify the namespace to update.
  // Format: projects/{project_id}/namespaces/{namespace}
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "biglake.googleapis.com/Namespace"
    }
  ];

  // Required. The update to apply to the namespace.
  IcebergNamespaceUpdate iceberg_namespace_update = 2
      [(google.api.field_behavior) = REQUIRED];
}

// The response message for the `UpdateIcebergNamespace` API.
message UpdateIcebergNamespaceResponse {
  // Output only. List of properties that were removed.
  repeated string removed = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. List of properties that were added or updated.
  repeated string updated = 2
      [json_name = "added", (google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. List of properties that were requested to be removed, but were
  // not found.
  repeated string missing = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// The request message for the `DeleteIcebergNamespace` API.
message DeleteIcebergNamespaceRequest {
  // Required. Iceberg namespace to delete in the format:
  // `projects/{project_id}/namespaces/{namespace}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "biglake.googleapis.com/Namespace"
    }
  ];
}

// The namespace object to create.
message IcebergNamespace {
  // Required. The name of the namespace.
  repeated string namespace = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The optional properties of the namespace.
  map<string, string> properties = 2 [(google.api.field_behavior) = OPTIONAL];
}

// The request message for the `CreateIcebergNamespace` API.
message CreateIcebergNamespaceRequest {
  // Required. The parent resource where this namespace will be created.
  // Format: projects/{project_id}/restcatalog/v1/catalogs/{catalog_id}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "biglake.googleapis.com/Catalog" }
  ];

  // Required. The namespace to create.
  IcebergNamespace iceberg_namespace = 2
      [json_name = "namespace", (google.api.field_behavior) = REQUIRED];
}

// The request message for the `GetIcebergCatalogConfig` API.
message GetIcebergCatalogConfigRequest {
  // Required. Warehouse location or identifier to request from the service.
  string warehouse = 1 [(google.api.field_behavior) = REQUIRED];
}

// The iceberg catalog configuration.
message IcebergCatalogConfig {
  // Output only. Properties that should be used to override client
  // configuration; applied after defaults and client configuration. Required,
  // even if empty.
  map<string, string> overrides = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Properties that should be used as default configuration;
  // applied before client configuration. Required, even if empty.
  map<string, string> defaults = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Endpoints, required, must not be empty.
  repeated string endpoints = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// The request message for the `GetIcebergNamespace` API.
message GetIcebergNamespaceRequest {
  // Required. Iceberg namespace to fetch in the format:
  // `projects/{project_id}/namespaces/{namespace}`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "biglake.googleapis.com/Namespace"
    }
  ];
}

// ListIcebergNamespacesRequest
message ListIcebergNamespacesRequest {
  // Optional. PageToken
  string page_token = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. For servers that support pagination, this signals an upper bound
  // of the number of results that a client will receive. For servers that do
  // not support pagination, clients may receive results larger than the
  // indicated `pageSize`.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Required. The parent from the resource path.
  string api_parent = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. An optional namespace, underneath which to list namespaces. If
  // not provided or empty, all top-level namespaces should be listed. If parent
  // is a multipart namespace, the parts must be separated by the unit separator
  // (`0x1F`) byte.
  // Not a real parent, so ST_NOT_REQUIRED.
  string parent = 4 [(google.api.field_behavior) = OPTIONAL];
}

// The response message for the `ListIcebergNamespaces` API.
message ListIcebergNamespacesResponse {
  // The list of namespaces.
  repeated google.protobuf.ListValue namespaces = 1;

  // The next page token for pagination.
  string next_page_token = 2 [json_name = "next-page-token"];
}

// The storage credential for a path in the table.
message StorageCredential {
  // Indicates a storage location prefix where the credential is relevant.
  string prefix = 1;

  // The credentials for the storage location. The keys that are populated are:
  // - `gcs.oauth2.token`
  // - `gcs.oauth2.token_expires_at`
  // - `expiration-time` (to support federation from Polaris).
  map<string, string> config = 2;
}

// The response message for the `LoadCredentials` API.
message LoadIcebergTableCredentialsResponse {
  // The credentials for the table assigned to the caller.
  repeated StorageCredential storage_credentials = 1
      [json_name = "storage-credentials"];
}
