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

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/resource.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/empty.proto";
import "google/streetview/publish/v1/resources.proto";
import "google/streetview/publish/v1/rpcmessages.proto";

option go_package = "cloud.google.com/go/streetview/publish/apiv1/publishpb;publishpb";
option java_outer_classname = "StreetViewPublish";
option java_package = "com.google.geo.ugc.streetview.publish.v1";
option (google.api.resource_definition) = {
  type: "streetviewpublish.googleapis.com/Contract"
  pattern: "contracts/{contract}"
};

// Definition of the service that backs the Street View Publish API.

// Publishes and connects user-contributed photos on Street View.
service StreetViewPublishService {
  option (google.api.default_host) = "streetviewpublish.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/streetviewpublish";

  // Creates an upload session to start uploading photo bytes.  The method uses
  // the upload URL of the returned
  // [UploadRef][google.streetview.publish.v1.UploadRef] to upload the bytes for
  // the [Photo][google.streetview.publish.v1.Photo].
  //
  // In addition to the photo requirements shown in
  // https://support.google.com/maps/answer/7012050?ref_topic=6275604,
  // the photo must meet the following requirements:
  //
  // * Photo Sphere XMP metadata must be included in the photo metadata. See
  // https://developers.google.com/streetview/spherical-metadata for the
  // required fields.
  // * The pixel size of the photo must meet the size requirements listed in
  // https://support.google.com/maps/answer/7012050?ref_topic=6275604, and
  // the photo must be a full 360 horizontally.
  //
  // After the upload completes, the method uses
  // [UploadRef][google.streetview.publish.v1.UploadRef] with
  // [CreatePhoto][google.streetview.publish.v1.StreetViewPublishService.CreatePhoto]
  // to create the [Photo][google.streetview.publish.v1.Photo] object entry.
  rpc StartUpload(google.protobuf.Empty) returns (UploadRef) {
    option (google.api.http) = {
      post: "/v1/photo:startUpload"
      body: "*"
    };
  }

  // After the client finishes uploading the photo with the returned
  // [UploadRef][google.streetview.publish.v1.UploadRef],
  // [CreatePhoto][google.streetview.publish.v1.StreetViewPublishService.CreatePhoto]
  // publishes the uploaded [Photo][google.streetview.publish.v1.Photo] to
  // Street View on Google Maps.
  //
  // Currently, the only way to set heading, pitch, and roll in CreatePhoto is
  // through the [Photo Sphere XMP
  // metadata](https://developers.google.com/streetview/spherical-metadata) in
  // the photo bytes. CreatePhoto ignores the  `pose.heading`, `pose.pitch`,
  // `pose.roll`, `pose.altitude`, and `pose.level` fields in Pose.
  //
  // This method returns the following error codes:
  //
  // * [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT] if
  // the request is malformed or if the uploaded photo is not a 360 photo.
  // * [google.rpc.Code.NOT_FOUND][google.rpc.Code.NOT_FOUND] if the upload
  // reference does not exist.
  // * [google.rpc.Code.RESOURCE_EXHAUSTED][google.rpc.Code.RESOURCE_EXHAUSTED]
  // if the account has reached the storage limit.
  rpc CreatePhoto(CreatePhotoRequest) returns (Photo) {
    option (google.api.http) = {
      post: "/v1/photo"
      body: "photo"
    };
    option (google.api.method_signature) = "photo";
  }

  // Gets the metadata of the specified
  // [Photo][google.streetview.publish.v1.Photo].
  //
  // This method returns the following error codes:
  //
  // * [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED] if
  // the requesting user did not create the requested
  // [Photo][google.streetview.publish.v1.Photo].
  // * [google.rpc.Code.NOT_FOUND][google.rpc.Code.NOT_FOUND] if the requested
  // [Photo][google.streetview.publish.v1.Photo] does not exist.
  // * [google.rpc.Code.UNAVAILABLE][google.rpc.Code.UNAVAILABLE] if the
  // requested [Photo][google.streetview.publish.v1.Photo] is still being
  // indexed.
  rpc GetPhoto(GetPhotoRequest) returns (Photo) {
    option (google.api.http) = {
      get: "/v1/photo/{photo_id}"
    };
    option (google.api.method_signature) = "photo_id,view";
  }

  // Gets the metadata of the specified
  // [Photo][google.streetview.publish.v1.Photo] batch.
  //
  // Note that if
  // [BatchGetPhotos][google.streetview.publish.v1.StreetViewPublishService.BatchGetPhotos]
  // fails, either critical fields are missing or there is an authentication
  // error. Even if
  // [BatchGetPhotos][google.streetview.publish.v1.StreetViewPublishService.BatchGetPhotos]
  // succeeds, individual photos in the batch may have failures.
  // These failures are specified in each
  // [PhotoResponse.status][google.streetview.publish.v1.PhotoResponse.status]
  // in
  // [BatchGetPhotosResponse.results][google.streetview.publish.v1.BatchGetPhotosResponse.results].
  // See
  // [GetPhoto][google.streetview.publish.v1.StreetViewPublishService.GetPhoto]
  // for specific failures that can occur per photo.
  rpc BatchGetPhotos(BatchGetPhotosRequest) returns (BatchGetPhotosResponse) {
    option (google.api.http) = {
      get: "/v1/photos:batchGet"
    };
    option (google.api.method_signature) = "view,photo_ids";
  }

  // Lists all the [Photos][google.streetview.publish.v1.Photo] that belong to
  // the user.
  //
  // > Note: Recently created photos that are still
  // being indexed are not returned in the response.
  rpc ListPhotos(ListPhotosRequest) returns (ListPhotosResponse) {
    option (google.api.http) = {
      get: "/v1/photos"
    };
    option (google.api.method_signature) = "view,filter";
  }

  // Updates the metadata of a [Photo][google.streetview.publish.v1.Photo], such
  // as pose, place association, connections, etc. Changing the pixels of a
  // photo is not supported.
  //
  // Only the fields specified in the
  // [updateMask][google.streetview.publish.v1.UpdatePhotoRequest.update_mask]
  // field are used. If `updateMask` is not present, the update applies to all
  // fields.
  //
  // This method returns the following error codes:
  //
  // * [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED] if
  // the requesting user did not create the requested photo.
  // * [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT] if
  // the request is malformed.
  // * [google.rpc.Code.NOT_FOUND][google.rpc.Code.NOT_FOUND] if the requested
  // photo does not exist.
  // * [google.rpc.Code.UNAVAILABLE][google.rpc.Code.UNAVAILABLE] if the
  // requested [Photo][google.streetview.publish.v1.Photo] is still being
  // indexed.
  rpc UpdatePhoto(UpdatePhotoRequest) returns (Photo) {
    option (google.api.http) = {
      put: "/v1/photo/{photo.photo_id.id}"
      body: "photo"
    };
    option (google.api.method_signature) = "photo,update_mask";
  }

  // Updates the metadata of [Photos][google.streetview.publish.v1.Photo], such
  // as pose, place association, connections, etc. Changing the pixels of photos
  // is not supported.
  //
  // Note that if
  // [BatchUpdatePhotos][google.streetview.publish.v1.StreetViewPublishService.BatchUpdatePhotos]
  // fails, either critical fields are missing or there is an authentication
  // error. Even if
  // [BatchUpdatePhotos][google.streetview.publish.v1.StreetViewPublishService.BatchUpdatePhotos]
  // succeeds, individual photos in the batch may have failures.
  // These failures are specified in each
  // [PhotoResponse.status][google.streetview.publish.v1.PhotoResponse.status]
  // in
  // [BatchUpdatePhotosResponse.results][google.streetview.publish.v1.BatchUpdatePhotosResponse.results].
  // See
  // [UpdatePhoto][google.streetview.publish.v1.StreetViewPublishService.UpdatePhoto]
  // for specific failures that can occur per photo.
  //
  // Only the fields specified in
  // [updateMask][google.streetview.publish.v1.UpdatePhotoRequest.update_mask]
  // field are used. If `updateMask` is not present, the update applies to all
  // fields.
  //
  // The number of
  // [UpdatePhotoRequest][google.streetview.publish.v1.UpdatePhotoRequest]
  // messages in a
  // [BatchUpdatePhotosRequest][google.streetview.publish.v1.BatchUpdatePhotosRequest]
  // must not exceed 20.
  //
  // > Note: To update
  // [Pose.altitude][google.streetview.publish.v1.Pose.altitude],
  // [Pose.latLngPair][google.streetview.publish.v1.Pose.lat_lng_pair] has to be
  // filled as well. Otherwise, the request will fail.
  rpc BatchUpdatePhotos(BatchUpdatePhotosRequest)
      returns (BatchUpdatePhotosResponse) {
    option (google.api.http) = {
      post: "/v1/photos:batchUpdate"
      body: "*"
    };
    option (google.api.method_signature) = "update_photo_requests";
  }

  // Deletes a [Photo][google.streetview.publish.v1.Photo] and its metadata.
  //
  // This method returns the following error codes:
  //
  // * [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED] if
  // the requesting user did not create the requested photo.
  // * [google.rpc.Code.NOT_FOUND][google.rpc.Code.NOT_FOUND] if the photo ID
  // does not exist.
  rpc DeletePhoto(DeletePhotoRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/photo/{photo_id}"
    };
    option (google.api.method_signature) = "photo_id";
  }

  // Deletes a list of [Photos][google.streetview.publish.v1.Photo] and their
  // metadata.
  //
  // Note that if
  // [BatchDeletePhotos][google.streetview.publish.v1.StreetViewPublishService.BatchDeletePhotos]
  // fails, either critical fields are missing or there is an authentication
  // error. Even if
  // [BatchDeletePhotos][google.streetview.publish.v1.StreetViewPublishService.BatchDeletePhotos]
  // succeeds, individual photos in the batch may have failures.
  // These failures are specified in each
  // [PhotoResponse.status][google.streetview.publish.v1.PhotoResponse.status]
  // in
  // [BatchDeletePhotosResponse.results][google.streetview.publish.v1.BatchDeletePhotosResponse.status].
  // See
  // [DeletePhoto][google.streetview.publish.v1.StreetViewPublishService.DeletePhoto]
  // for specific failures that can occur per photo.
  rpc BatchDeletePhotos(BatchDeletePhotosRequest)
      returns (BatchDeletePhotosResponse) {
    option (google.api.http) = {
      post: "/v1/photos:batchDelete"
      body: "*"
    };
    option (google.api.method_signature) = "photo_ids";
  }

  // Creates an upload session to start uploading photo sequence data.
  // The upload URL of the returned
  // [UploadRef][google.streetview.publish.v1.UploadRef] is used to upload the
  // data for the `photoSequence`.
  //
  // After the upload is complete, the
  // [UploadRef][google.streetview.publish.v1.UploadRef] is used with
  // [CreatePhotoSequence][google.streetview.publish.v1.StreetViewPublishService.CreatePhotoSequence]
  // to create the [PhotoSequence][google.streetview.publish.v1.PhotoSequence]
  // object entry.
  rpc StartPhotoSequenceUpload(google.protobuf.Empty) returns (UploadRef) {
    option (google.api.http) = {
      post: "/v1/photoSequence:startUpload"
      body: "*"
    };
  }

  // After the client finishes uploading the
  // [PhotoSequence][google.streetview.publish.v1.PhotoSequence] with the
  // returned [UploadRef][google.streetview.publish.v1.UploadRef],
  // [CreatePhotoSequence][google.streetview.publish.v1.StreetViewPublishService.CreatePhotoSequence]
  // extracts a sequence of 360 photos from a video or Extensible Device
  // Metadata (XDM, http://www.xdm.org/) to be published to Street View on
  // Google Maps.
  //
  // `CreatePhotoSequence` returns an [Operation][google.longrunning.Operation],
  // with the [PhotoSequence][google.streetview.publish.v1.PhotoSequence] Id set
  // in the `Operation.name` field.
  //
  // This method returns the following error codes:
  //
  // * [google.rpc.Code.INVALID_ARGUMENT][google.rpc.Code.INVALID_ARGUMENT] if
  // the request is malformed.
  // * [google.rpc.Code.NOT_FOUND][google.rpc.Code.NOT_FOUND] if the upload
  // reference does not exist.
  rpc CreatePhotoSequence(CreatePhotoSequenceRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/photoSequence"
      body: "photo_sequence"
    };
    option (google.api.method_signature) = "photo_sequence,input_type";
    option (google.longrunning.operation_info) = {
      response_type: "PhotoSequence"
      metadata_type: "google.protobuf.Empty"
    };
  }

  // Gets the metadata of the specified
  // [PhotoSequence][google.streetview.publish.v1.PhotoSequence] via the
  // [Operation][google.longrunning.Operation] interface.
  //
  // This method returns the following three types of responses:
  //
  // * `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` is poulated, which
  //   contains a [PhotoSequence][google.streetview.publish.v1.PhotoSequence]
  //   message.
  //
  // This method returns the following error codes:
  //
  // * [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED] if
  // the requesting user did not create the requested
  // [PhotoSequence][google.streetview.publish.v1.PhotoSequence].
  // * [google.rpc.Code.NOT_FOUND][google.rpc.Code.NOT_FOUND] if the requested
  // [PhotoSequence][google.streetview.publish.v1.PhotoSequence] does not exist.
  rpc GetPhotoSequence(GetPhotoSequenceRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      get: "/v1/photoSequence/{sequence_id}"
    };
    option (google.longrunning.operation_info) = {
      response_type: "PhotoSequence"
      metadata_type: "google.protobuf.Empty"
    };
  }

  // Lists all the [PhotoSequences][google.streetview.publish.v1.PhotoSequence]
  // that belong to the user, in descending CreatePhotoSequence timestamp order.
  rpc ListPhotoSequences(ListPhotoSequencesRequest)
      returns (ListPhotoSequencesResponse) {
    option (google.api.http) = {
      get: "/v1/photoSequences"
    };
  }

  // Deletes a [PhotoSequence][google.streetview.publish.v1.PhotoSequence] and
  // its metadata.
  //
  // This method returns the following error codes:
  //
  // * [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED] if
  // the requesting user did not create the requested photo sequence.
  // * [google.rpc.Code.NOT_FOUND][google.rpc.Code.NOT_FOUND] if the photo
  // sequence ID does not exist.
  // * [google.rpc.Code.FAILED_PRECONDITION][google.rpc.Code.FAILED_PRECONDITION] if the photo sequence ID is not
  // yet finished processing.
  rpc DeletePhotoSequence(DeletePhotoSequenceRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/photoSequence/{sequence_id}"
    };
    option (google.api.method_signature) = "sequence_id";
  }
}
