// Copyright 2019 The Nakama Authors
//
// 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.

/**
 * The Nakama server RPC protocol for games and apps.
 */
syntax = "proto3";

package nakama.api;

import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";

option go_package = "github.com/heroiclabs/nakama-common/api";

option java_multiple_files = true;
option java_outer_classname = "NakamaApi";
option java_package = "com.heroiclabs.nakama.api";

option csharp_namespace = "Nakama.Protobuf";

// A user with additional account details. Always the current user.
message Account {
  // The user object.
  User user = 1;
  // The user's wallet data.
  string wallet = 2;
  // The email address of the user.
  string email = 3;
  // The devices which belong to the user's account.
  repeated AccountDevice devices = 4;
  // The custom id in the user's account.
  string custom_id = 5;
  // The UNIX time when the user's email was verified.
  google.protobuf.Timestamp verify_time = 6;
  // The UNIX time when the user's account was disabled/banned.
  google.protobuf.Timestamp disable_time = 7;
}

// Obtain a new authentication token using a refresh token.
message AccountRefresh {
  // Refresh token.
  string token = 1;
  // Extra information that will be bundled in the session token.
  map<string, string> vars = 2;
}

// Send a Apple Sign In token to the server. Used with authenticate/link/unlink.
message AccountApple {
  // The ID token received from Apple to validate.
  string token = 1;
  // Extra information that will be bundled in the session token.
  map<string, string> vars = 2;
}

// Send a custom ID to the server. Used with authenticate/link/unlink.
message AccountCustom {
  // A custom identifier.
  string id = 1;
  // Extra information that will be bundled in the session token.
  map<string, string> vars = 2;
}

// Send a device to the server. Used with authenticate/link/unlink and user.
message AccountDevice {
  // A device identifier. Should be obtained by a platform-specific device API.
  string id = 1;
  // Extra information that will be bundled in the session token.
  map<string, string> vars = 2;
}

// Send an email with password to the server. Used with authenticate/link/unlink.
message AccountEmail {
  // A valid RFC-5322 email address.
  string email = 1;
  // A password for the user account.
  string password = 2; // Ignored with unlink operations.
  // Extra information that will be bundled in the session token.
  map<string, string> vars = 3;
}

// Send a Facebook token to the server. Used with authenticate/link/unlink.
message AccountFacebook {
  // The OAuth token received from Facebook to access their profile API.
  string token = 1;
  // Extra information that will be bundled in the session token.
  map<string, string> vars = 2;
}

// Send a Facebook Instant Game token to the server. Used with authenticate/link/unlink.
message AccountFacebookInstantGame {
  // The OAuth token received from a Facebook Instant Game that may be decoded with the Application Secret (must be available with the nakama configuration)
  string signed_player_info = 1;
  // Extra information that will be bundled in the session token.
  map<string, string> vars = 2;
}

// Send Apple's Game Center account credentials to the server. Used with authenticate/link/unlink.
message AccountGameCenter {
  // https://developer.apple.com/documentation/gamekit/gklocalplayer/1515407-generateidentityverificationsign

  // Player ID (generated by GameCenter).
  string player_id = 1;
  // Bundle ID (generated by GameCenter).
  string bundle_id = 2;
  // Time since UNIX epoch when the signature was created.
  int64 timestamp_seconds = 3;
  // A random "NSString" used to compute the hash and keep it randomized.
  string salt = 4;
  // The verification signature data generated.
  string signature = 5;
  // The URL for the public encryption key.
  string public_key_url = 6;
  // Extra information that will be bundled in the session token.
  map<string, string> vars = 7;
}

// Send a Google token to the server. Used with authenticate/link/unlink.
message AccountGoogle {
  // The OAuth token received from Google to access their profile API.
  string token = 1;
  // Extra information that will be bundled in the session token.
  map<string, string> vars = 2;
}

// Send a Steam token to the server. Used with authenticate/link/unlink.
message AccountSteam {
  // The account token received from Steam to access their profile API.
  string token = 1;
  // Extra information that will be bundled in the session token.
  map<string, string> vars = 2;
}

// Add one or more friends to the current user.
message AddFriendsRequest {
  // The account id of a user.
  repeated string ids = 1;
  // The account username of a user.
  repeated string usernames = 2;
}

// Add users to a group.
message AddGroupUsersRequest {
  // The group to add users to.
  string group_id = 1;
  // The users to add.
  repeated string user_ids = 2;
}

// Authenticate against the server with a refresh token.
message SessionRefreshRequest {
  // Refresh token.
  string token = 1;
  // Extra information that will be bundled in the session token.
  map<string, string> vars = 2;
}

// Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user.
message SessionLogoutRequest {
  // Session token to log out.
  string token = 1;
  // Refresh token to invalidate.
  string refresh_token = 2;
}

// Authenticate against the server with Apple Sign In.
message AuthenticateAppleRequest {
  // The Apple account details.
  AccountApple account = 1;
  // Register the account if the user does not already exist.
  google.protobuf.BoolValue create = 2;
  // Set the username on the account at register. Must be unique.
  string username = 3;
}

// Authenticate against the server with a custom ID.
message AuthenticateCustomRequest {
  // The custom account details.
  AccountCustom account = 1;
  // Register the account if the user does not already exist.
  google.protobuf.BoolValue create = 2;
  // Set the username on the account at register. Must be unique.
  string username = 3;
}

// Authenticate against the server with a device ID.
message AuthenticateDeviceRequest {
  // The device account details.
  AccountDevice account = 1;
  // Register the account if the user does not already exist.
  google.protobuf.BoolValue create = 2;
  // Set the username on the account at register. Must be unique.
  string username = 3;
}

// Authenticate against the server with email+password.
message AuthenticateEmailRequest {
  // The email account details.
  AccountEmail account = 1;
  // Register the account if the user does not already exist.
  google.protobuf.BoolValue create = 2;
  // Set the username on the account at register. Must be unique.
  string username = 3;
}

// Authenticate against the server with Facebook.
message AuthenticateFacebookRequest {
  // The Facebook account details.
  AccountFacebook account = 1;
  // Register the account if the user does not already exist.
  google.protobuf.BoolValue create = 2;
  // Set the username on the account at register. Must be unique.
  string username = 3;
  // Import Facebook friends for the user.
  google.protobuf.BoolValue sync = 4;
}

// Authenticate against the server with Facebook Instant Game token.
message AuthenticateFacebookInstantGameRequest {
  // The Facebook Instant Game account details.
  AccountFacebookInstantGame account = 1;
  // Register the account if the user does not already exist.
  google.protobuf.BoolValue create = 2;
  // Set the username on the account at register. Must be unique.
  string username = 3;
}

// Authenticate against the server with Apple's Game Center.
message AuthenticateGameCenterRequest {
  // The Game Center account details.
  AccountGameCenter account = 1;
  // Register the account if the user does not already exist.
  google.protobuf.BoolValue create = 2;
  // Set the username on the account at register. Must be unique.
  string username = 3;
}

// Authenticate against the server with Google.
message AuthenticateGoogleRequest {
  // The Google account details.
  AccountGoogle account = 1;
  // Register the account if the user does not already exist.
  google.protobuf.BoolValue create = 2;
  // Set the username on the account at register. Must be unique.
  string username = 3;
}

// Authenticate against the server with Steam.
message AuthenticateSteamRequest {
  // The Steam account details.
  AccountSteam account = 1;
  // Register the account if the user does not already exist.
  google.protobuf.BoolValue create = 2;
  // Set the username on the account at register. Must be unique.
  string username = 3;
  // Import Steam friends for the user.
  google.protobuf.BoolValue sync = 4;
}

// Ban users from a group.
message BanGroupUsersRequest {
  // The group to ban users from.
  string group_id = 1;
  // The users to ban.
  repeated string user_ids = 2;
}

// Block one or more friends for the current user.
message BlockFriendsRequest {
  // The account id of a user.
  repeated string ids = 1;
  // The account username of a user.
  repeated string usernames = 2;
}

// A message sent on a channel.
message ChannelMessage {
  // The channel this message belongs to.
  string channel_id = 1;
  // The unique ID of this message.
  string message_id = 2;
  // The code representing a message type or category.
  google.protobuf.Int32Value code = 3;
  // Message sender, usually a user ID.
  string sender_id = 4;
  // The username of the message sender, if any.
  string username = 5;
  // The content payload.
  string content = 6;
  // The UNIX time when the message was created.
  google.protobuf.Timestamp create_time = 7;
  // The UNIX time when the message was last updated.
  google.protobuf.Timestamp update_time = 8;
  // True if the message was persisted to the channel's history, false otherwise.
  google.protobuf.BoolValue persistent = 9;
  // The name of the chat room, or an empty string if this message was not sent through a chat room.
  string room_name = 10;
  // The ID of the group, or an empty string if this message was not sent through a group channel.
  string group_id = 11;
  // The ID of the first DM user, or an empty string if this message was not sent through a DM chat.
  string user_id_one = 12;
  // The ID of the second DM user, or an empty string if this message was not sent through a DM chat.
  string user_id_two = 13;
}

// A list of channel messages, usually a result of a list operation.
message ChannelMessageList {
  // A list of messages.
  repeated ChannelMessage messages = 1;
  // The cursor to send when retrieving the next page, if any.
  string next_cursor = 2;
  // The cursor to send when retrieving the previous page, if any.
  string prev_cursor = 3;
  // Cacheable cursor to list newer messages. Durable and designed to be stored, unlike next/prev cursors.
  string cacheable_cursor = 4;
}

// Create a group with the current user as owner.
message CreateGroupRequest {
  // A unique name for the group.
  string name = 1;
  // A description for the group.
  string description = 2;
  // The language expected to be a tag which follows the BCP-47 spec.
  string lang_tag = 3;
  // A URL for an avatar image.
  string avatar_url = 4;
  // Mark a group as open or not where only admins can accept members.
  bool open = 5;
  // Maximum number of group members.
  int32 max_count = 6;
}

// Delete one or more friends for the current user.
message DeleteFriendsRequest {
  // The account id of a user.
  repeated string ids = 1;
  // The account username of a user.
  repeated string usernames = 2;
}

// Delete a group the user has access to.
message DeleteGroupRequest {
  // The id of a group.
  string group_id = 1;
}

// Delete a leaderboard record.
message DeleteLeaderboardRecordRequest {
  // The leaderboard ID to delete from.
  string leaderboard_id = 1;
}

// Delete one or more notifications for the current user.
message DeleteNotificationsRequest {
  // The id of notifications.
  repeated string ids = 1;
}

// Storage objects to delete.
message DeleteStorageObjectId {
  // The collection which stores the object.
  string collection = 1;
  // The key of the object within the collection.
  string key = 2;
  // The version hash of the object.
  string version = 3;
}

// Batch delete storage objects.
message DeleteStorageObjectsRequest {
  // Batch of storage objects.
  repeated DeleteStorageObjectId object_ids = 1;
}

// Represents an event to be passed through the server to registered event handlers.
message Event {
  // An event name, type, category, or identifier.
  string name = 1;
  // Arbitrary event property values.
  map<string, string> properties = 2;
  // The time when the event was triggered.
  google.protobuf.Timestamp timestamp = 3;
  // True if the event came directly from a client call, false otherwise.
  bool external = 4;
}

// A friend of a user.
message Friend {
  // The friendship status.
  enum State {
    // The user is a friend of the current user.
    FRIEND = 0;
    // The current user has sent an invite to the user.
    INVITE_SENT = 1;
    // The current user has received an invite from this user.
    INVITE_RECEIVED = 2;
    // The current user has blocked this user.
    BLOCKED = 3;
  }

  // The user object.
  User user = 1;
  // The friend status.
  google.protobuf.Int32Value state = 2; // one of "Friend.State".
  // Time of the latest relationship update.
  google.protobuf.Timestamp update_time = 3;
}

// A collection of zero or more friends of the user.
message FriendList {
  // The Friend objects.
  repeated Friend friends = 1;
  // Cursor for the next page of results, if any.
  string cursor = 2;
}

// Fetch a batch of zero or more users from the server.
message GetUsersRequest {
  // The account id of a user.
  repeated string ids = 1;
  // The account username of a user.
  repeated string usernames = 2;
  // The Facebook ID of a user.
  repeated string facebook_ids = 3;
}

// Fetch a subscription by product id.
message GetSubscriptionRequest {
  // Product id of the subscription
  string product_id = 1;
}

// A group in the server.
message Group {
  // The id of a group.
  string id = 1;
  // The id of the user who created the group.
  string creator_id = 2;
  // The unique name of the group.
  string name = 3;
  // A description for the group.
  string description = 4;
  // The language expected to be a tag which follows the BCP-47 spec.
  string lang_tag = 5;
  // Additional information stored as a JSON object.
  string metadata = 6;
  // A URL for an avatar image.
  string avatar_url = 7;
  // Anyone can join open groups, otherwise only admins can accept members.
  google.protobuf.BoolValue open = 8;
  // The current count of all members in the group.
  int32 edge_count = 9;
  // The maximum number of members allowed.
  int32 max_count = 10;
  // The UNIX time when the group was created.
  google.protobuf.Timestamp create_time = 11;
  // The UNIX time when the group was last updated.
  google.protobuf.Timestamp update_time = 12;
}

// One or more groups returned from a listing operation.
message GroupList {
  // One or more groups.
  repeated Group groups = 1;
  // A cursor used to get the next page.
  string cursor = 2;
}

// A list of users belonging to a group, along with their role.
message GroupUserList {
  // A single user-role pair.
  message GroupUser {
    // The group role status.
    enum State {
      // The user is a superadmin with full control of the group.
      SUPERADMIN = 0;
      // The user is an admin with additional privileges.
      ADMIN = 1;
      // The user is a regular member.
      MEMBER = 2;
      // The user has requested to join the group
      JOIN_REQUEST = 3;
    }

    // User.
    User user = 1;
    // Their relationship to the group.
    google.protobuf.Int32Value state = 2;
  }

  // User-role pairs for a group.
  repeated GroupUser group_users = 1;
  // Cursor for the next page of results, if any.
  string cursor = 2;
}

// Import Facebook friends into the current user's account.
message ImportFacebookFriendsRequest {
  // The Facebook account details.
  AccountFacebook account = 1;
  // Reset the current user's friends list.
  google.protobuf.BoolValue reset = 2;
}

// Import Facebook friends into the current user's account.
message ImportSteamFriendsRequest {
  // The Facebook account details.
  AccountSteam account = 1;
  // Reset the current user's friends list.
  google.protobuf.BoolValue reset = 2;
}

// Immediately join an open group, or request to join a closed one.
message JoinGroupRequest {
  // The group ID to join. The group must already exist.
  string group_id = 1;
}

// The request to join a tournament.
message JoinTournamentRequest {
  // The ID of the tournament to join. The tournament must already exist.
  string tournament_id = 1;
}

// Kick a set of users from a group.
message KickGroupUsersRequest {
  // The group ID to kick from.
  string group_id = 1;
  // The users to kick.
  repeated string user_ids = 2;
}

// A leaderboard on the server.
message Leaderboard {
  // The ID of the leaderboard.
  string id = 1;
  // ASC(0) or DESC(1) sort mode of scores in the leaderboard.
  uint32 sort_order = 2;
  // BEST, SET, INCREMENT or DECREMENT operator mode of the leaderboard.
  Operator operator = 3;
  // The UNIX time when the leaderboard was previously reset. A computed value.
  uint32 prev_reset = 4;
  // The UNIX time when the leaderboard is next playable. A computed value.
  uint32 next_reset = 5;
  // Additional information stored as a JSON object.
  string metadata = 6;
  // The UNIX time when the leaderboard was created.
  google.protobuf.Timestamp create_time = 7;
  // Whether the leaderboard was created authoritatively or not.
  bool authoritative = 8;
}

// A list of leaderboards
message LeaderboardList {
  // The list of leaderboards returned.
  repeated Leaderboard leaderboards = 1;
  // A pagination cursor (optional).
  string cursor = 2;
}

// Represents a complete leaderboard record with all scores and associated metadata.
message LeaderboardRecord {
  // The ID of the leaderboard this score belongs to.
  string leaderboard_id = 1;
  // The ID of the score owner, usually a user or group.
  string owner_id = 2;
  // The username of the score owner, if the owner is a user.
  google.protobuf.StringValue username = 3;
  // The score value.
  int64 score = 4;
  // An optional subscore value.
  int64 subscore = 5;
  // The number of submissions to this score record.
  int32 num_score = 6;
  // Metadata.
  string metadata = 7;
  // The UNIX time when the leaderboard record was created.
  google.protobuf.Timestamp create_time = 8;
  // The UNIX time when the leaderboard record was updated.
  google.protobuf.Timestamp update_time = 9;
  // The UNIX time when the leaderboard record expires.
  google.protobuf.Timestamp expiry_time = 10;
  // The rank of this record.
  int64 rank = 11;
  // The maximum number of score updates allowed by the owner.
  uint32 max_num_score = 12;
}

// A set of leaderboard records, may be part of a leaderboard records page or a batch of individual records.
message LeaderboardRecordList {
  // A list of leaderboard records.
  repeated LeaderboardRecord records = 1;
  // A batched set of leaderboard records belonging to specified owners.
  repeated LeaderboardRecord owner_records = 2;
  // The cursor to send when retrieving the next page, if any.
  string next_cursor = 3;
  // The cursor to send when retrieving the previous page, if any.
  string prev_cursor = 4;
}

// Leave a group.
message LeaveGroupRequest {
  // The group ID to leave.
  string group_id = 1;
}

// Link Facebook to the current user's account.
message LinkFacebookRequest {
  // The Facebook account details.
  AccountFacebook account = 1;
  // Import Facebook friends for the user.
  google.protobuf.BoolValue sync = 2;
}

// Link Steam to the current user's account.
message LinkSteamRequest {
  // The Facebook account details.
  AccountSteam account = 1;
  // Import Steam friends for the user.
  google.protobuf.BoolValue sync = 2;
}

// List a channel's message history.
message ListChannelMessagesRequest {
  // The channel ID to list from.
  string channel_id = 1;
  // Max number of records to return. Between 1 and 100.
  google.protobuf.Int32Value limit = 2;
  // True if listing should be older messages to newer, false if reverse.
  google.protobuf.BoolValue forward = 3;
  // A pagination cursor, if any.
  string cursor = 4;
}

// List friends for a user.
message ListFriendsRequest {
  // Max number of records to return. Between 1 and 100.
  google.protobuf.Int32Value limit = 1;
  // The friend state to list.
  google.protobuf.Int32Value state = 2;
  // An optional next page cursor.
  string cursor = 3;
}

// List groups based on given filters.
message ListGroupsRequest {
  // List groups that contain this value in their names.
  string name = 1;
  // Optional pagination cursor.
  string cursor = 2;
  // Max number of groups to return. Between 1 and 100.
  google.protobuf.Int32Value limit = 3;
  // Language tag filter
  string lang_tag = 4;
  // Number of group members
  google.protobuf.Int32Value members = 5;
  // Optional Open/Closed filter.
  google.protobuf.BoolValue open = 6;
}

// List all users that are part of a group.
message ListGroupUsersRequest {
  // The group ID to list from.
  string group_id = 1;
  // Max number of records to return. Between 1 and 100.
  google.protobuf.Int32Value limit = 2;
  // The group user state to list.
  google.protobuf.Int32Value state = 3;
  // An optional next page cursor.
  string cursor = 4;
}

// List leaerboard records from a given leaderboard around the owner.
message ListLeaderboardRecordsAroundOwnerRequest {
  // The ID of the tournament to list for.
  string leaderboard_id = 1;
  // Max number of records to return. Between 1 and 100.
  google.protobuf.UInt32Value limit = 2;
  // The owner to retrieve records around.
  string owner_id = 3;
  // Expiry in seconds (since epoch) to begin fetching records from.
  google.protobuf.Int64Value expiry = 4;
  // A next or previous page cursor.
  string cursor = 5;
}

// List leaderboard records from a given leaderboard.
message ListLeaderboardRecordsRequest {
  // The ID of the leaderboard to list for.
  string leaderboard_id = 1;
  // One or more owners to retrieve records for.
  repeated string owner_ids = 2;
  // Max number of records to return. Between 1 and 100.
  google.protobuf.Int32Value limit = 3;
  // A next or previous page cursor.
  string cursor = 4;
  // Expiry in seconds (since epoch) to begin fetching records from. Optional. 0 means from current time.
  google.protobuf.Int64Value expiry = 5;
}

// List realtime matches.
message ListMatchesRequest {
  // Limit the number of returned matches.
  google.protobuf.Int32Value limit = 1;
  // Authoritative or relayed matches.
  google.protobuf.BoolValue authoritative = 2;
  // Label filter.
  google.protobuf.StringValue label = 3;
  // Minimum user count.
  google.protobuf.Int32Value min_size = 4;
  // Maximum user count.
  google.protobuf.Int32Value max_size = 5;
  // Arbitrary label query.
  google.protobuf.StringValue query = 6;
}

// Get a list of unexpired notifications.
message ListNotificationsRequest {
  // The number of notifications to get. Between 1 and 100.
  google.protobuf.Int32Value limit = 1;
  // A cursor to page through notifications. May be cached by clients to get from point in time forwards.
  string cacheable_cursor = 2; // value from NotificationList.cacheable_cursor.
}

// List publicly readable storage objects in a given collection.
message ListStorageObjectsRequest {
  // ID of the user.
  string user_id = 1;
  // The collection which stores the object.
  string collection = 2;
  // The number of storage objects to list. Between 1 and 100.
  google.protobuf.Int32Value limit = 3;
  // The cursor to page through results from.
  string cursor = 4; // value from StorageObjectList.cursor.
}

// List user subscriptions.
message ListSubscriptionsRequest {
  // Max number of results per page
  google.protobuf.Int32Value limit = 1;
  // Cursor to retrieve a page of records from
  string cursor = 2;
}

// List tournament records from a given tournament around the owner.
message ListTournamentRecordsAroundOwnerRequest {
  // The ID of the tournament to list for.
  string tournament_id = 1;
  // Max number of records to return. Between 1 and 100.
  google.protobuf.UInt32Value limit = 2;
  // The owner to retrieve records around.
  string owner_id = 3;
  // Expiry in seconds (since epoch) to begin fetching records from.
  google.protobuf.Int64Value expiry = 4;
  // A next or previous page cursor.
  string cursor = 5;
}

// List tournament records from a given tournament.
message ListTournamentRecordsRequest {
  // The ID of the tournament to list for.
  string tournament_id = 1;
  // One or more owners to retrieve records for.
  repeated string owner_ids = 2;
  // Max number of records to return. Between 1 and 100.
  google.protobuf.Int32Value limit = 3;
  // A next or previous page cursor.
  string cursor = 4;
  // Expiry in seconds (since epoch) to begin fetching records from.
  google.protobuf.Int64Value expiry = 5;
}

// List active/upcoming tournaments based on given filters.
message ListTournamentsRequest {
  // The start of the categories to include. Defaults to 0.
  google.protobuf.UInt32Value category_start = 1;
  // The end of the categories to include. Defaults to 128.
  google.protobuf.UInt32Value category_end = 2;
  // The start time for tournaments. Defaults to epoch.
  google.protobuf.UInt32Value start_time = 3;
  // The end time for tournaments. Defaults to +1 year from current Unix time.
  google.protobuf.UInt32Value end_time = 4;
  // Max number of records to return. Between 1 and 100.
  google.protobuf.Int32Value limit = 6;
  // A next page cursor for listings (optional).
  string cursor = 8;
}

// List the groups a user is part of, and their relationship to each.
message ListUserGroupsRequest {
  // ID of the user.
  string user_id = 1;
  // Max number of records to return. Between 1 and 100.
  google.protobuf.Int32Value limit = 2;
  // The user group state to list.
  google.protobuf.Int32Value state = 3;
  // An optional next page cursor.
  string cursor = 4;
}

// Represents a realtime match.
message Match {
  // The ID of the match, can be used to join.
  string match_id = 1;
  // True if it's an server-managed authoritative match, false otherwise.
  bool authoritative = 2;
  // Match label, if any.
  google.protobuf.StringValue label = 3;
  // Current number of users in the match.
  int32 size = 4;
  // Tick Rate
  int32 tick_rate = 5;
  // Handler name
  string handler_name = 6;
}

// A list of realtime matches.
message MatchList {
  // A number of matches corresponding to a list operation.
  repeated Match matches = 1;
}

// A notification in the server.
message Notification {
  // ID of the Notification.
  string id = 1;
  // Subject of the notification.
  string subject = 2;
  // Content of the notification in JSON.
  string content = 3;
  // Category code for this notification.
  int32 code = 4;
  // ID of the sender, if a user. Otherwise 'null'.
  string sender_id = 5;
  // The UNIX time when the notification was created.
  google.protobuf.Timestamp create_time = 6;
  // True if this notification was persisted to the database.
  bool persistent = 7;
}

// A collection of zero or more notifications.
message NotificationList {
  // Collection of notifications.
  repeated Notification notifications = 1;
  // Use this cursor to paginate notifications. Cache this to catch up to new notifications.
  string cacheable_cursor = 2;
}

// Promote a set of users in a group to the next role up.
message PromoteGroupUsersRequest {
  // The group ID to promote in.
  string group_id = 1;
  // The users to promote.
  repeated string user_ids = 2;
}

// Demote a set of users in a group to the next role down.
message DemoteGroupUsersRequest {
  // The group ID to demote in.
  string group_id = 1;
  // The users to demote.
  repeated string user_ids = 2;
}

// Storage objects to get.
message ReadStorageObjectId {
  // The collection which stores the object.
  string collection = 1;
  // The key of the object within the collection.
  string key = 2;
  // The user owner of the object.
  string user_id = 3;
}

// Batch get storage objects.
message ReadStorageObjectsRequest {
  // Batch of storage objects.
  repeated ReadStorageObjectId object_ids = 1;
}

// Execute an Lua function on the server.
message Rpc {
  // The identifier of the function.
  string id = 1;
  // The payload of the function which must be a JSON object.
  string payload = 2;
  // The authentication key used when executed as a non-client HTTP request.
  string http_key = 3;
}

// A user's session used to authenticate messages.
message Session {
  // True if the corresponding account was just created, false otherwise.
  bool created = 1;
  // Authentication credentials.
  string token = 2;
  // Refresh token that can be used for session token renewal.
  string refresh_token = 3;
}

// An object within the storage engine.
message StorageObject {
  // The collection which stores the object.
  string collection = 1;
  // The key of the object within the collection.
  string key = 2;
  // The user owner of the object.
  string user_id = 3;
  // The value of the object.
  string value = 4;
  // The version hash of the object.
  string version = 5;
  // The read access permissions for the object.
  int32 permission_read = 6;
  // The write access permissions for the object.
  int32 permission_write = 7;
  // The UNIX time when the object was created.
  google.protobuf.Timestamp create_time = 8;
  // The UNIX time when the object was last updated.
  google.protobuf.Timestamp update_time = 9;
}

// A storage acknowledgement.
message StorageObjectAck {
  // The collection which stores the object.
  string collection = 1;
  // The key of the object within the collection.
  string key = 2;
  // The version hash of the object.
  string version = 3;
  // The owner of the object.
  string user_id = 4;
}

// Batch of acknowledgements for the storage object write.
message StorageObjectAcks {
  // Batch of storage write acknowledgements.
  repeated StorageObjectAck acks = 1;
}

// Batch of storage objects.
message StorageObjects {
  // The batch of storage objects.
  repeated StorageObject objects = 1;
}

// List of storage objects.
message StorageObjectList {
  // The list of storage objects.
  repeated StorageObject objects = 1;
  // The cursor for the next page of results, if any.
  string cursor = 2;
}

// A tournament on the server.
message Tournament {
  // The ID of the tournament.
  string id = 1;
  // The title for the tournament.
  string title = 2;
  // The description of the tournament. May be blank.
  string description = 3;
  // The category of the tournament. e.g. "vip" could be category 1.
  uint32 category = 4;
  // ASC (0) or DESC (1) sort mode of scores in the tournament.
  uint32 sort_order = 5;
  // The current number of players in the tournament.
  uint32 size = 6;
  // The maximum number of players for the tournament.
  uint32 max_size = 7;
  // The maximum score updates allowed per player for the current tournament.
  uint32 max_num_score = 8;
  // True if the tournament is active and can enter. A computed value.
  bool can_enter = 9;
  // The UNIX time when the tournament stops being active until next reset. A computed value.
  uint32 end_active = 10;
  // The UNIX time when the tournament is next playable. A computed value.
  uint32 next_reset = 11;
  // Additional information stored as a JSON object.
  string metadata = 12;
  // The UNIX time when the tournament was created.
  google.protobuf.Timestamp create_time = 13;
  // The UNIX time when the tournament will start.
  google.protobuf.Timestamp start_time = 14;
  // The UNIX time when the tournament will be stopped.
  google.protobuf.Timestamp end_time = 15;
  // Duration of the tournament in seconds.
  uint32 duration = 16;
  // The UNIX time when the tournament start being active. A computed value.
  uint32 start_active = 17;
  // The UNIX time when the tournament was last reset. A computed value.
  uint32 prev_reset = 18;
  // Operator.
  Operator operator = 19;
  // Whether the leaderboard was created authoritatively or not.
  bool authoritative = 20;
}

// A list of tournaments.
message TournamentList {
  // The list of tournaments returned.
  repeated Tournament tournaments = 1;
  // A pagination cursor (optional).
  string cursor = 2;
}

// A set of tournament records which may be part of a tournament records page or a batch of individual records.
message TournamentRecordList {
  // A list of tournament records.
  repeated LeaderboardRecord records = 1;
  // A batched set of tournament records belonging to specified owners.
  repeated LeaderboardRecord owner_records = 2;
  // The cursor to send when retireving the next page (optional).
  string next_cursor = 3;
  // The cursor to send when retrieving the previous page (optional).
  string prev_cursor = 4;
}

// Update a user's account details.
message UpdateAccountRequest {
  // The username of the user's account.
  google.protobuf.StringValue username = 1;
  // The display name of the user.
  google.protobuf.StringValue display_name = 2;
  // A URL for an avatar image.
  google.protobuf.StringValue avatar_url = 3;
  // The language expected to be a tag which follows the BCP-47 spec.
  google.protobuf.StringValue lang_tag = 4;
  // The location set by the user.
  google.protobuf.StringValue location = 5;
  // The timezone set by the user.
  google.protobuf.StringValue timezone = 6;
}

// Update fields in a given group.
message UpdateGroupRequest {
  // The ID of the group to update.
  string group_id = 1;
  // Name.
  google.protobuf.StringValue name = 2;
  // Description string.
  google.protobuf.StringValue description = 3;
  // Lang tag.
  google.protobuf.StringValue lang_tag = 4;
  // Avatar URL.
  google.protobuf.StringValue avatar_url = 5;
  // Open is true if anyone should be allowed to join, or false if joins must be approved by a group admin.
  google.protobuf.BoolValue open = 6;
}

// A user in the server.
message User {
  // The id of the user's account.
  string id = 1;
  // The username of the user's account.
  string username = 2;
  // The display name of the user.
  string display_name = 3;
  // A URL for an avatar image.
  string avatar_url = 4;
  // The language expected to be a tag which follows the BCP-47 spec.
  string lang_tag = 5;
  // The location set by the user.
  string location = 6;
  // The timezone set by the user.
  string timezone = 7;
  // Additional information stored as a JSON object.
  string metadata = 8;
  // The Facebook id in the user's account.
  string facebook_id = 9;
  // The Google id in the user's account.
  string google_id = 10;
  // The Apple Game Center in of the user's account.
  string gamecenter_id = 11;
  // The Steam id in the user's account.
  string steam_id = 12;
  // Indicates whether the user is currently online.
  bool online = 13;
  // Number of related edges to this user.
  int32 edge_count = 14;
  // The UNIX time when the user was created.
  google.protobuf.Timestamp create_time = 15;
  // The UNIX time when the user was last updated.
  google.protobuf.Timestamp update_time = 16;
  // The Facebook Instant Game ID in the user's account.
  string facebook_instant_game_id = 17;
  // The Apple Sign In ID in the user's account.
  string apple_id = 18;
}

// A list of groups belonging to a user, along with the user's role in each group.
message UserGroupList {
  // A single group-role pair.
  message UserGroup {
    // The group role status.
    enum State {
      // The user is a superadmin with full control of the group.
      SUPERADMIN = 0;
      // The user is an admin with additional privileges.
      ADMIN = 1;
      // The user is a regular member.
      MEMBER = 2;
      // The user has requested to join the group
      JOIN_REQUEST = 3;
    }

    // Group.
    Group group = 1;
    // The user's relationship to the group.
    google.protobuf.Int32Value state = 2;
  }

  // Group-role pairs for a user.
  repeated UserGroup user_groups = 1;
  // Cursor for the next page of results, if any.
  string cursor = 2;
}

// A collection of zero or more users.
message Users {
  // The User objects.
  repeated User users = 1;
}

// Apple IAP Purchases validation request
message ValidatePurchaseAppleRequest {
  // Base64 encoded Apple receipt data payload.
  string receipt = 1;
  // Persist the purchase
  google.protobuf.BoolValue persist = 2;
}

// Apple Subscription validation request
message ValidateSubscriptionAppleRequest {
  // Base64 encoded Apple receipt data payload.
  string receipt = 1;
  // Persist the subscription.
  google.protobuf.BoolValue persist = 2;
}

// Google IAP Purchase validation request
message ValidatePurchaseGoogleRequest {
  // JSON encoded Google purchase payload.
  string purchase = 1;
  // Persist the purchase
  google.protobuf.BoolValue persist = 2;
}

// Google Subscription validation request
message ValidateSubscriptionGoogleRequest {
  // JSON encoded Google purchase payload.
  string receipt = 1;
  // Persist the subscription.
  google.protobuf.BoolValue persist = 2;
}

// Huawei IAP Purchase validation request
message ValidatePurchaseHuaweiRequest {
  // JSON encoded Huawei InAppPurchaseData.
  string purchase = 1;
  // InAppPurchaseData signature.
  string signature = 2;
  // Persist the purchase
  google.protobuf.BoolValue persist = 3;
}

// Validated Purchase stored by Nakama.
message ValidatedPurchase {
 // Purchase Product ID.
  string product_id = 1;
  // Purchase Transaction ID.
  string transaction_id = 2;
  // Store identifier
  StoreProvider store = 3;
  // UNIX Timestamp when the purchase was done.
  google.protobuf.Timestamp purchase_time = 4;
  // UNIX Timestamp when the receipt validation was stored in DB.
  google.protobuf.Timestamp create_time = 5;
  // UNIX Timestamp when the receipt validation was updated in DB.
  google.protobuf.Timestamp update_time = 6;
  // Raw provider validation response.
  string provider_response = 7;
  // Whether the purchase was done in production or sandbox environment.
  StoreEnvironment environment = 8;
  // Whether the purchase had already been validated by Nakama before.
  bool seen_before = 9;
}

// Validate IAP response.
message ValidatePurchaseResponse {
  // Newly seen validated purchases.
  repeated ValidatedPurchase validated_purchases = 1;
}

// Validate Subscription response.
message ValidateSubscriptionResponse {
  ValidatedSubscription validated_subscription = 1;
}

// Validation Provider,
enum StoreProvider {
  // Apple App Store
  APPLE_APP_STORE = 0;
  // Google Play Store
  GOOGLE_PLAY_STORE = 1;
  // Huawei App Gallery
  HUAWEI_APP_GALLERY = 2;
}

// Environment where a purchase/subscription took place,
enum StoreEnvironment {
  // Unknown environment.
  UNKNOWN = 0;
  // Sandbox/test environment.
  SANDBOX = 1;
  // Production environment.
  PRODUCTION = 2;
}

message ValidatedSubscription {
  // Purchase Product ID.
  string product_id = 1;
  // Purchase Original transaction ID (we only keep track of the original subscription, not subsequent renewals).
  string original_transaction_id = 2;
  // Store identifier
  StoreProvider store = 3;
  // UNIX Timestamp when the purchase was done.
  google.protobuf.Timestamp purchase_time = 4;
  // UNIX Timestamp when the receipt validation was stored in DB.
  google.protobuf.Timestamp create_time = 5;
  // UNIX Timestamp when the receipt validation was updated in DB.
  google.protobuf.Timestamp update_time = 6;
  // Whether the purchase was done in production or sandbox environment.
  StoreEnvironment environment = 7;
  // Subscription expiration time. The subscription can still be auto-renewed to extend the expiration time further.
  google.protobuf.Timestamp expiry_time = 8;
  // Whether the subscription is currently active or not.
  bool active = 9;
}

// A list of validated purchases stored by Nakama.
message PurchaseList {
  // Stored validated purchases.
  repeated ValidatedPurchase validated_purchases = 1;
  // The cursor to send when retrieving the next page, if any.
  string cursor = 2;
  // The cursor to send when retrieving the previous page, if any.
  string prev_cursor = 3;
}

// A list of validated subscriptions stored by Nakama.
message SubscriptionList {
  // Stored validated subscriptions.
  repeated ValidatedSubscription validated_subscriptions = 1;
  // The cursor to send when retrieving the next page, if any.
  string cursor = 2;
  // The cursor to send when retrieving the previous page, if any.
  string prev_cursor = 3;
}

// A request to submit a score to a leaderboard.
message WriteLeaderboardRecordRequest {
  // Record values to write.
  message LeaderboardRecordWrite {
    // The score value to submit.
    int64 score = 1;
    // An optional secondary value.
    int64 subscore = 2;
    // Optional record metadata.
    string metadata = 3;
    // Operator override.
    Operator operator = 4;
  }

  // The ID of the leaderboard to write to.
  string leaderboard_id = 1;
  // Record input.
  LeaderboardRecordWrite record = 2;
}

// The object to store.
message WriteStorageObject {
  // The collection to store the object.
  string collection = 1;
  // The key for the object within the collection.
  string key = 2;
  // The value of the object.
  string value = 3;
  // The version hash of the object to check. Possible values are: ["", "*", "#hash#"].
  string version = 4; // if-match and if-none-match
  // The read access permissions for the object.
  google.protobuf.Int32Value permission_read = 5;
  // The write access permissions for the object.
  google.protobuf.Int32Value permission_write = 6;
}

// Write objects to the storage engine.
message WriteStorageObjectsRequest {
  // The objects to store on the server.
  repeated WriteStorageObject objects = 1;
}

// A request to submit a score to a tournament.
message WriteTournamentRecordRequest {
  // Record values to write.
  message TournamentRecordWrite {
    // The score value to submit.
    int64 score = 1;
    // An optional secondary value.
    int64 subscore = 2;
    // A JSON object of additional properties (optional).
    string metadata = 3;
    // Operator override.
    Operator operator = 4;
  }

  // The tournament ID to write the record for.
  string tournament_id = 1;
  // Record input.
  TournamentRecordWrite record = 2;
}

// Operator that can be used to override the one set in the leaderboard.
enum Operator {
  // Do not override the leaderboard operator.
  NO_OVERRIDE = 0;
  // Override the leaderboard operator with BEST.
  BEST = 1;
  // Override the leaderboard operator with SET.
  SET = 2;
  // Override the leaderboard operator with INCREMENT.
  INCREMENT = 3;
  // Override the leaderboard operator with DECREMENT.
  DECREMENT = 4;
}
