// Copyright 2023 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.streetview.publish.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/field_mask.proto";
import "google/rpc/status.proto";
import "google/streetview/publish/v1/resources.proto";

option go_package = "google.golang.org/genproto/googleapis/streetview/publish/v1;publish";
option java_outer_classname = "StreetViewPublishRpcMessages";
option java_package = "com.google.geo.ugc.streetview.publish.v1";

// Request to create a [Photo][google.streetview.publish.v1.Photo].
message CreatePhotoRequest {
  // Required. Photo to create.
  Photo photo = 1 [(google.api.field_behavior) = REQUIRED];
}

// Request to get a [Photo][google.streetview.publish.v1.Photo].
//
// By default
//
// * does not return the download URL for the photo bytes.
//
// Parameters:
//
// * `view` controls if the download URL for the photo bytes is returned.
message GetPhotoRequest {
  // Required. ID of the [Photo][google.streetview.publish.v1.Photo].
  string photo_id = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Specifies if a download URL for the photo bytes should be
  // returned in the [Photo][google.streetview.publish.v1.Photo] response.
  PhotoView view = 2 [(google.api.field_behavior) = REQUIRED];

  // The BCP-47 language code, such as "en-US" or "sr-Latn". For more
  // information, see
  // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
  // If language_code is unspecified, the user's language preference for Google
  // services is used.
  string language_code = 3;
}

// Request to get one or more [Photos][google.streetview.publish.v1.Photo].
// By default
//
// * does not return the download URL for the photo bytes.
//
// Parameters:
//
// * `view` controls if the download URL for the photo bytes is returned.
message BatchGetPhotosRequest {
  // Required. IDs of the [Photos][google.streetview.publish.v1.Photo]. For HTTP
  // GET requests, the URL query parameter should be
  // `photoIds=<id1>&photoIds=<id2>&...`.
  repeated string photo_ids = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Specifies if a download URL for the photo bytes should be
  // returned in the Photo response.
  PhotoView view = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. The BCP-47 language code, such as "en-US" or "sr-Latn". For more
  // information, see
  // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
  // If language_code is unspecified, the user's language preference for Google
  // services is used.
  string language_code = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response to batch get of [Photos][google.streetview.publish.v1.Photo].
message BatchGetPhotosResponse {
  // List of results for each individual
  // [Photo][google.streetview.publish.v1.Photo] requested, in the same order as
  // the requests in
  // [BatchGetPhotos][google.streetview.publish.v1.StreetViewPublishService.BatchGetPhotos].
  repeated PhotoResponse results = 1;
}

// Response payload for a single
// [Photo][google.streetview.publish.v1.Photo]
// in batch operations including
// [BatchGetPhotos][google.streetview.publish.v1.StreetViewPublishService.BatchGetPhotos]
// and
// [BatchUpdatePhotos][google.streetview.publish.v1.StreetViewPublishService.BatchUpdatePhotos].
message PhotoResponse {
  // The status for the operation to get or update a single photo in the batch
  // request.
  google.rpc.Status status = 1;

  // The [Photo][google.streetview.publish.v1.Photo] resource, if the request
  // was successful.
  Photo photo = 2;
}

// Request to list all photos that belong to the user sending the request.
//
// By default
//
// * does not return the download URL for the photo bytes.
//
// Parameters:
//
// * `view` controls if the download URL for the photo bytes is returned.
// * `pageSize` determines the maximum number of photos to return.
// * `pageToken` is the next page token value returned from a previous
// [ListPhotos][google.streetview.publish.v1.StreetViewPublishService.ListPhotos]
//     request, if any.
// * `filter` allows filtering by a given parameter. 'placeId' is the only
// parameter supported at the moment.
message ListPhotosRequest {
  // Required. Specifies if a download URL for the photos bytes should be
  // returned in the Photos response.
  PhotoView view = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The maximum number of photos to return.
  // `pageSize` must be non-negative. If `pageSize` is zero or is not provided,
  // the default page size of 100 is used.
  // The number of photos returned in the response may be less than `pageSize`
  // if the number of photos that belong to the user is less than `pageSize`.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The
  // [nextPageToken][google.streetview.publish.v1.ListPhotosResponse.next_page_token]
  // value returned from a previous
  // [ListPhotos][google.streetview.publish.v1.StreetViewPublishService.ListPhotos]
  // request, if any.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The filter expression. For example:
  // `placeId=ChIJj61dQgK6j4AR4GeTYWZsKWw`.
  //
  // The filters supported are: `placeId`, `min_latitude`, `max_latitude`,
  // `min_longitude`, `max_longitude`. See https://google.aip.dev/160 for more
  // information.
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The BCP-47 language code, such as "en-US" or "sr-Latn". For more
  // information, see
  // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
  // If language_code is unspecified, the user's language preference for Google
  // services is used.
  string language_code = 5 [(google.api.field_behavior) = OPTIONAL];
}

// Response to list all photos that belong to a user.
message ListPhotosResponse {
  // List of photos. The
  // [pageSize][google.streetview.publish.v1.ListPhotosRequest.page_size] field
  // in the request determines the number of items returned.
  repeated Photo photos = 1;

  // Token to retrieve the next page of results, or empty if there are no more
  // results in the list.
  string next_page_token = 2;
}

// Request to update the metadata of a
// [Photo][google.streetview.publish.v1.Photo]. Updating the pixels of a photo
// is not supported.
message UpdatePhotoRequest {
  // Required. [Photo][google.streetview.publish.v1.Photo] object containing the
  // new metadata.
  Photo photo = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Mask that identifies fields on the photo metadata to update.
  // If not present, the old [Photo][google.streetview.publish.v1.Photo]
  // metadata is entirely replaced with the
  // new [Photo][google.streetview.publish.v1.Photo] metadata in this request.
  // The update fails if invalid fields are specified. Multiple fields can be
  // specified in a comma-delimited list.
  //
  // The following fields are valid:
  //
  // * `pose.heading`
  // * `pose.lat_lng_pair`
  // * `pose.pitch`
  // * `pose.roll`
  // * `pose.level`
  // * `pose.altitude`
  // * `connections`
  // * `places`
  //
  //
  // > Note: When
  // [updateMask][google.streetview.publish.v1.UpdatePhotoRequest.update_mask]
  // contains repeated fields, the entire set of repeated values get replaced
  // with the new contents. For example, if
  // [updateMask][google.streetview.publish.v1.UpdatePhotoRequest.update_mask]
  // contains `connections` and `UpdatePhotoRequest.photo.connections` is empty,
  // all connections are removed.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Request to update the metadata of photos.
// Updating the pixels of photos is not supported.
message BatchUpdatePhotosRequest {
  // Required. List of
  // [UpdatePhotoRequests][google.streetview.publish.v1.UpdatePhotoRequest].
  repeated UpdatePhotoRequest update_photo_requests = 1
      [(google.api.field_behavior) = REQUIRED];
}

// Response to batch update of metadata of one or more
// [Photos][google.streetview.publish.v1.Photo].
message BatchUpdatePhotosResponse {
  // List of results for each individual
  // [Photo][google.streetview.publish.v1.Photo] updated, in the same order as
  // the request.
  repeated PhotoResponse results = 1;
}

// Request to delete a [Photo][google.streetview.publish.v1.Photo].
message DeletePhotoRequest {
  // Required. ID of the [Photo][google.streetview.publish.v1.Photo].
  string photo_id = 1 [(google.api.field_behavior) = REQUIRED];
}

// Request to delete multiple [Photos][google.streetview.publish.v1.Photo].
message BatchDeletePhotosRequest {
  // Required. IDs of the [Photos][google.streetview.publish.v1.Photo]. HTTP
  // GET requests require the following syntax for the URL query parameter:
  // `photoIds=<id1>&photoIds=<id2>&...`.
  repeated string photo_ids = 1 [(google.api.field_behavior) = REQUIRED];
}

// Request to create a
// [PhotoSequence][google.streetview.publish.v1.PhotoSequence] from a video.
message CreatePhotoSequenceRequest {
  // Input forms of [PhotoSequence][google.streetview.publish.v1.PhotoSequence].
  enum InputType {
    // Not specified. Server will return
    // [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT].
    INPUT_TYPE_UNSPECIFIED = 0;

    // 360 Video.
    VIDEO = 1;

    // Extensible Device Metadata, http://www.xdm.org
    XDM = 2;
  }

  // Required. [PhotoSequence][google.streetview.publish.v1.PhotoSequence] to
  // create.
  PhotoSequence photo_sequence = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The input form of
  // [PhotoSequence][google.streetview.publish.v1.PhotoSequence].
  InputType input_type = 2 [(google.api.field_behavior) = REQUIRED];
}

// Request to get a [PhotoSequence][google.streetview.publish.v1.PhotoSequence].
//
// By default
//
// * does not return the download URL for the
// [PhotoSequence][google.streetview.publish.v1.PhotoSequence].
//
// Parameters:
//
// * `view` controls if the download URL for the
// [PhotoSequence][google.streetview.publish.v1.PhotoSequence] is
//   returned.
message GetPhotoSequenceRequest {
  // Required. ID of the photo sequence.
  string sequence_id = 1 [(google.api.field_behavior) = REQUIRED];

  // Specifies if a download URL for the photo sequence should be returned in
  // `download_url` of individual photos in the
  // [PhotoSequence][google.streetview.publish.v1.PhotoSequence] response.
  // > Note: Currently not implemented.
  PhotoView view = 2 [deprecated = true];

  // Optional. The filter expression. For example: `published_status=PUBLISHED`.
  //
  // The filters supported are: `published_status`.  See
  // https://google.aip.dev/160 for more information.
  string filter = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Request to delete a
// [PhotoSequence][google.streetview.publish.v1.PhotoSequence].
message DeletePhotoSequenceRequest {
  // Required. ID of the
  // [PhotoSequence][google.streetview.publish.v1.PhotoSequence].
  string sequence_id = 1 [(google.api.field_behavior) = REQUIRED];
}

// Response to batch delete of one or more
// [Photos][google.streetview.publish.v1.Photo].
message BatchDeletePhotosResponse {
  // The status for the operation to delete a single
  // [Photo][google.streetview.publish.v1.Photo] in the batch request.
  repeated google.rpc.Status status = 1;
}

// Request to list all photo sequences that belong to the user sending the
// request.
//
// Parameters:
//
// * `pageSize` determines the maximum number of photo sequences to return.
// * `pageToken` is the next page token value returned from a previous
// [ListPhotoSequences][google.streetview.publish.v1.StreetViewPublishService.ListPhotoSequences]
//   request, if any.
message ListPhotoSequencesRequest {
  // Optional. The maximum number of photo sequences to return.
  // `pageSize` must be non-negative. If `pageSize` is zero or is not
  // provided, the default page size of 100 is used.
  // The number of photo sequences returned in the response may be less than
  // `pageSize` if the number of matches is less than `pageSize`.
  // This is currently unimplemented but is in process.
  int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The
  // [nextPageToken][google.streetview.publish.v1.ListPhotosResponse.next_page_token]
  // value returned from a previous
  // [ListPhotoSequences][google.streetview.publish.v1.StreetViewPublishService.ListPhotoSequences]
  // request, if any.
  string page_token = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The filter expression. For example: `imagery_type=SPHERICAL`.
  //
  // The filters supported are: `imagery_type`, `processing_state`,
  // `min_latitude`, `max_latitude`, `min_longitude`, `max_longitude`,
  // `filename_query`, `min_capture_time_seconds`, `max_capture_time_seconds.
  // See https://google.aip.dev/160 for more information. Filename queries
  // should sent as a Phrase in order to support multiple words and special
  // characters by adding escaped quotes. Ex: filename_query="example of a
  // phrase.mp4"
  string filter = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Response to list all photo sequences that belong to a user.
message ListPhotoSequencesResponse {
  // List of photo sequences via [Operation][google.longrunning.Operation]
  // interface.
  //
  // The maximum number of items returned is based on the
  // [pageSize][google.streetview.publish.v1.ListPhotoSequencesRequest.page_size]
  // field in the request.
  //
  // Each item in the list can have three possible states,
  //
  // * `Operation.done` = false, if the processing of
  //   [PhotoSequence][google.streetview.publish.v1.PhotoSequence] is not
  //   finished yet.
  // * `Operation.done` = true and `Operation.error` is populated, if there was
  //   an error in processing.
  // * `Operation.done` = true and `Operation.response` contains a
  //   [PhotoSequence][google.streetview.publish.v1.PhotoSequence] message,
  //   In each sequence, only
  //   [Id][google.streetview.publish.v1.PhotoSequence.id] is populated.
  repeated google.longrunning.Operation photo_sequences = 1;

  // Token to retrieve the next page of results, or empty if there are no more
  // results in the list.
  string next_page_token = 2;
}

// Specifies which view of the [Photo][google.streetview.publish.v1.Photo]
// to include in the response.
enum PhotoView {
  // Server responses do not include the download URL for the photo bytes.
  // The default value.
  BASIC = 0;

  // Server responses include the download URL for the photo bytes.
  INCLUDE_DOWNLOAD_URL = 1;
}
