syntax = "proto3";

package connectstate;
import "player.proto";


option optimize_for = CODE_SIZE;
option java_package = "com.spotify.connectstate";

message ClusterUpdate {
    Cluster cluster = 1;
    ClusterUpdateReason update_reason = 2;
    string ack_id = 3;
    repeated string devices_that_changed = 4;
}

message Device {
    DeviceInfo device_info = 1;
    PlayerState player_state = 2;
    PrivateDeviceInfo private_device_info = 3;
}

message Cluster {
    int64 timestamp = 1;
    string active_device_id = 2;
    PlayerState player_state = 3;
    map<string, DeviceInfo> device = 4;
    bytes transfer_data = 5;
}

message PutStateRequest {
    string callback_url = 1;
    Device device = 2;
    MemberType member_type = 3;
    bool is_active = 4;
    PutStateReason put_state_reason = 5;
    uint32 message_id = 6;
    string last_command_sent_by_device_id = 7;
    uint32 last_command_message_id = 8;
    uint64 started_playing_at = 9;
    uint64 has_been_playing_for_ms = 11;
    uint64 client_side_timestamp = 12;
    bool only_write_player_state = 13;
}

message PrivateDeviceInfo {
    string platform = 1;
}

message SubscribeRequest {
    string callback_url = 1;
}

message DeviceInfo {
    bool can_play = 1;
    uint32 volume = 2;
    string name = 3;
    Capabilities capabilities = 4;
    string device_software_version = 6;
    DeviceType device_type = 7;
    string spirc_version = 9;
    string device_id = 10;
    bool is_private_session = 11;
    bool is_social_connect = 12;
    string client_id = 13;
    string brand = 14;
    string model = 15;
    map<string, string> metadata_map = 16;
}

message Capabilities {
    bool can_be_player = 2;
    bool restrict_to_local = 3;
    bool gaia_eq_connect_id = 5;
    bool supports_logout = 6;
    bool is_observable = 7;
    int32 volume_steps = 8;
    repeated string supported_types = 9;
    bool command_acks = 10;
    bool supports_rename = 11;
    bool hidden = 12;
    bool disable_volume = 13;
    bool connect_disabled = 14;
    bool supports_playlist_v2 = 15;
    bool is_controllable = 16;
    bool supports_external_episodes = 17;
    bool supports_set_backend_metadata = 18;
    bool supports_transfer_command = 19;
    bool supports_command_request = 20;
    bool is_voice_enabled = 21;
    bool needs_full_player_state = 22;
    bool supports_gzip_pushes = 23;
    // reserved 1, "supported_contexts";
}

message ConnectCommandOptions {
    int32 message_id = 1;
}

message LogoutCommand {
    ConnectCommandOptions command_options = 1;
}

message SetVolumeCommand {
    int32 volume = 1;
    ConnectCommandOptions command_options = 2;
}

message RenameCommand {
    string rename_to = 1;
    ConnectCommandOptions command_options = 2;
}

message SetBackendMetadataCommand {
    map<string, string> metadata = 1;
}

enum SendCommandResult {
    UNKNOWN_SEND_COMMAND_RESULT = 0;
    SUCCESS = 1;
    DEVICE_NOT_FOUND = 2;
    CONTEXT_PLAYER_ERROR = 3;
    DEVICE_DISAPPEARED = 4;
    UPSTREAM_ERROR = 5;
    DEVICE_DOES_NOT_SUPPORT_COMMAND = 6;
    RATE_LIMITED = 7;
}

enum PutStateReason {
    UNKNOWN_PUT_STATE_REASON = 0;
    SPIRC_HELLO = 1;
    SPIRC_NOTIFY = 2;
    NEW_DEVICE = 3;
    PLAYER_STATE_CHANGED = 4;
    VOLUME_CHANGED = 5;
    PICKER_OPENED = 6;
    BECAME_INACTIVE = 7;
}

enum MemberType {
    SPIRC_V2 = 0;
    SPIRC_V3 = 1;
    CONNECT_STATE = 2;
}

enum ClusterUpdateReason {
    UNKNOWN_CLUSTER_UPDATE_REASON = 0;
    DEVICES_DISAPPEARED = 1;
    DEVICE_STATE_CHANGED = 2;
    NEW_DEVICE_APPEARED = 3;
}

enum DeviceType {
    UNKNOWN = 0;
    COMPUTER = 1;
    TABLET = 2;
    SMARTPHONE = 3;
    SPEAKER = 4;
    TV = 5;
    AVR = 6;
    STB = 7;
    AUDIO_DONGLE = 8;
    GAME_CONSOLE = 9;
    CAST_VIDEO = 10;
    CAST_AUDIO = 11;
    AUTOMOBILE = 12;
    SMARTWATCH = 13;
    CHROMEBOOK = 14;
    UNKNOWN_SPOTIFY = 100;
    CAR_THING = 101;
    OBSERVER = 102;
    HOME_THING = 103;
}
