// 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.maps.playablelocations.v3;

import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "google/maps/playablelocations/v3/resources.proto";
import "google/maps/playablelocations/v3/sample/resources.proto";
import "google/maps/unity/clientinfo.proto";
import "google/protobuf/duration.proto";
import "google/api/client.proto";

option csharp_namespace = "Google.Maps.PlayableLocations.V3";
option go_package = "cloud.google.com/go/maps/playablelocations/apiv3/playablelocationspb;playablelocationspb";
option java_multiple_files = true;
option java_outer_classname = "PlayableLocationsProto";
option java_package = "com.google.maps.playablelocations.v3";
option php_namespace = "Google\\Maps\\PlayableLocations\\V3";
option objc_class_prefix = "GMPL";

// The Playable Locations API for v3.
service PlayableLocations {
  option (google.api.default_host) = "playablelocations.googleapis.com";

  // Returns a set of playable locations that lie within a specified area,
  // that satisfy optional filter criteria.
  //
  // Note: Identical `SamplePlayableLocations` requests can return different
  // results as the state of the world changes over time.
  rpc SamplePlayableLocations(SamplePlayableLocationsRequest)
      returns (SamplePlayableLocationsResponse) {
    option (google.api.http) = {
      post: "/v3:samplePlayableLocations"
      body: "*"
    };
  }

  // Logs bad playable location reports submitted by players.
  //
  // Reports are not partially saved; either all reports are saved and this
  // request succeeds, or no reports are saved, and this request fails.
  rpc LogPlayerReports(LogPlayerReportsRequest)
      returns (LogPlayerReportsResponse) {
    option (google.api.http) = {
      post: "/v3:logPlayerReports"
      body: "*"
    };
  }

  // Logs new events when playable locations are displayed, and when they are
  // interacted with.
  //
  // Impressions are not partially saved; either all impressions are saved and
  // this request succeeds, or no impressions are saved, and this request fails.
  rpc LogImpressions(LogImpressionsRequest) returns (LogImpressionsResponse) {
    option (google.api.http) = {
      post: "/v3:logImpressions"
      body: "*"
    };
  }
}

//
// Life of a query:
//
// - When a game starts in a new location, your game server issues a
// [SamplePlayableLocations][google.maps.playablelocations.v3.PlayableLocations.SamplePlayableLocations]
// request. The request specifies the S2 cell, and contains one or more
// "criteria" for filtering:
//
// - Criterion 0: i locations for long-lived bases, or level 0 monsters, or...
// - Criterion 1: j locations for short-lived bases, or level 1 monsters, ...
// - Criterion 2: k locations for random objects.
// - etc (up to 5 criterion may be specified).
//
// `PlayableLocationList` will then contain mutually
// exclusive lists of `PlayableLocation` objects that satisfy each of
// the criteria. Think of it as a collection of real-world locations that you
// can then associate with your game state.
//
// Note: These points are impermanent in nature. E.g, parks can close, and
// places can be removed.
//
// The response specifies how long you can expect the playable locations to
// last. Once they expire, you should query the `samplePlayableLocations` API
// again to get a fresh view of the real world.
message SamplePlayableLocationsRequest {
  // Required. Specifies the area to search within for playable locations.
  google.maps.playablelocations.v3.sample.AreaFilter area_filter = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. Specifies one or more (up to 5) criteria for filtering the
  // returned playable locations.
  repeated google.maps.playablelocations.v3.sample.Criterion criteria = 2
      [(google.api.field_behavior) = REQUIRED];
}

//
// Response for the
// [SamplePlayableLocations][google.maps.playablelocations.v3.PlayableLocations.SamplePlayableLocations]
// method.
message SamplePlayableLocationsResponse {
  // Each PlayableLocation object corresponds to a game_object_type specified
  // in the request.
  map<int32, google.maps.playablelocations.v3.sample.PlayableLocationList>
      locations_per_game_object_type = 1;

  // Required. Specifies the "time-to-live" for the set of playable locations.
  // You can use this value to determine how long to cache the set of playable
  // locations. After this length of time, your back-end game server should
  // issue a new
  // [SamplePlayableLocations][google.maps.playablelocations.v3.PlayableLocations.SamplePlayableLocations]
  // request to get a fresh set of playable locations (because for example, they
  // might have been removed, a park might have closed for the day, a
  // business might have closed permanently).
  google.protobuf.Duration ttl = 9;
}

// A request for logging your player's bad location reports.
message LogPlayerReportsRequest {
  // Required. Player reports. The maximum number of player reports that you can
  // log at once is 50.
  repeated PlayerReport player_reports = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. A string that uniquely identifies the log player reports request.
  // This allows you to detect duplicate requests. We recommend that you use
  // UUIDs for this value. The value must not exceed 50 characters.
  //
  // You should reuse the `request_id` only when retrying a request in the case
  // of a failure. In that case, the request must be identical to the one that
  // failed.
  string request_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Information about the client device (for example, device model
  // and operating system).
  google.maps.unity.ClientInfo client_info = 3
      [(google.api.field_behavior) = REQUIRED];
}

// A response for the
// [LogPlayerReports][google.maps.playablelocations.v3.PlayableLocations.LogPlayerReports]
// method.
//
// This method returns no data upon success.
message LogPlayerReportsResponse {}

// A request for logging impressions.
message LogImpressionsRequest {
  // Required. Impression event details. The maximum number of impression
  // reports that you can log at once is 50.
  repeated Impression impressions = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. A string that uniquely identifies the log impressions request.
  // This allows you to detect duplicate requests. We recommend that you use
  // UUIDs for this value. The value must not exceed 50 characters.
  //
  // You should reuse the `request_id` only when retrying a request in case of
  // failure. In this case, the request must be identical to the one that
  // failed.
  string request_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Information about the client device. For example, device model
  // and operating system.
  google.maps.unity.ClientInfo client_info = 3
      [(google.api.field_behavior) = REQUIRED];
}

// A response for the
// [LogImpressions][google.maps.playablelocations.v3.PlayableLocations.LogImpressions]
// method. This method returns no data upon success.
message LogImpressionsResponse {}
