syntax = "proto3";

package Aurora.Proto.Party;

import "general.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/field_mask.proto";

//Party
    //Members
        //EventSubscriptions
        //Events
    //Media

service RemotePartyService {
    //**************
    //Party Resource
    //**************
    //Get Party
    rpc GetParty(Aurora.Proto.General.Empty) returns (Party);

    //***************
    //Member Resource
    //***************
    //List
    rpc ListMembers(ListMembersRequest) returns (ListMembersResponse);
        
    //Get
    rpc GetMember(GetMemberRequest) returns (Member);

    //Update
    rpc UpdateMember(UpdateMemberRequest) returns (Member);

    //Create
    rpc CreateMember(CreateMemberRequest) returns (Member);

    //Delete
    rpc DeleteMember(DeleteMemberRequest) returns (Aurora.Proto.General.Empty) {};

    //**************
    //Media Resource
    //**************
    //List
    rpc ListMedia(ListMediaRequest) returns (ListMediaResponse);

    //Get
    rpc GetMedia(GetMediaRequest) returns (Media);

    //Create
    rpc CreateMedia(CreateMediaRequest) returns (Media);

    //Delete
    rpc DeleteMedia(DeleteMediaRequest) returns (Aurora.Proto.General.Empty) {};

    //CUSTOM: Stream
    rpc StreamMedia(StreamMediaRequest) returns (stream Aurora.Proto.General.Chunk) {};

    //CUSTOM: Sync
    rpc SyncMedia(SyncMediaRequest) returns (stream Sync) {};

    //***************************
    //EventSubscriptions Resource
    //***************************
    //List
    rpc ListEventSubscriptions(ListEventSubscriptionsRequest) returns (ListEventSubscriptionsResponse);

    //Create
    rpc CreateEventSubscription(CreateEventSubscriptionRequest) returns (EventSubscription);
    
    //Delete
    rpc DeleteEventSubscription(DeleteEventSubscriptionRequest) returns (Aurora.Proto.General.Empty);

    //CUSTOM: Create EventSubscription List
    rpc CreateEventSubscriptionList(CreateEventSubscriptionListRequest) returns (CreateEventSubscriptionListResponse);

    //CUSTOM: Delete all
    rpc DeleteAllEventSubscriptions(DeleteAllEventSubscriptionsRequest) returns (Aurora.Proto.General.Empty);
    
    //*****
    //Event 
    //*****
    //Get
    rpc GetEvents(GetEventsRequest) returns (stream BaseEvent) {};
}

message Party {
    //The resource name of the party
    string name = 1;
    string displayName = 2;
    string description = 3;
    string hostIp = 4;
    Member hostMember = 5;
    google.protobuf.Timestamp createdOn = 6;
}

enum PartyJoinedStatusEnum {
    InParty = 0;
    NotInParty = 1;
}

message LeavePartyResponse {
    PartyJoinedStatusEnum status = 1;
}

message Member {
    //Resource name of the party member to be returned (Added by server)
    string name = 1;
    string userName = 2;

    //Added by server
    string ipAddress = 3;
    
    //Added by server
    google.protobuf.Timestamp addedOn = 4;
}

message ListMembersRequest {
    //Resource name of the parent of the members collection to be returned (The party)
    string parent = 1;
    int32 pageSize = 2;
    string pageToken = 3;
}

message ListMembersResponse {
    repeated Member members = 1;
    string nextPageToken = 2;
}
message GetMemberRequest {
    //Resource name of the member to be returned
    string name = 1;
}

message CreateMemberRequest {
    //Resource name of the parent collection of the member to be created (The party)
    string parent = 1;
    Member member = 2;
}

message UpdateMemberRequest {
    Member member = 1;
    google.protobuf.FieldMask updateMask = 2;
}

message DeleteMemberRequest {
    //Resource name of the member to be deleted
    string name = 1;
}

message Media {
    //Resource name of the remote media object
    string name = 1;
    string title = 2;
    string artist = 3;
    string album = 4;
    string duration = 5;
}

message ListMediaRequest {
    //Resource name of the parent of the media collection to be listed (The party)
    string parent = 1;
    int32 pageSize = 2;
    string pageToken = 3;
}

message ListMediaResponse {
    repeated Media media = 1;
    string nextPageToken = 3;
}

message GetMediaRequest {
    //Resource name of the media requested
    string name = 1;
}

message CreateMediaRequest {
    //Resource name of the parent collection of the member to be created (The party)
    string parent = 1;
    Media media = 2;
}

message DeleteMediaRequest {
    //Resource name of the member to be deleted
    string name = 1;
}

message StreamMediaRequest {
    //Resource name of the media requested
    string name = 1;
}

message SyncMediaRequest {
    //Resource name of the media to sync with
    string name = 1;
}

message Sync {
    int64 serverTimeTicks = 1;
    float trackPosition= 2;
}

/* Event Types */
enum EventType {
    MemberCreated = 0;
    MemberDeleted = 1;
    MediaPlaying = 2;
    MediaStopped = 3;
}

message BaseEvent {
    //Resource name of the event ?
    string name = 1;
    EventType eventType = 2;
    string clientKey = 3;
    
    oneof derivedEvent {
        MemberCreatedEvent memberCreatedEvent = 4;
        MemberDeletedEvent memberDeletedEvent = 5;
        NewMediaPlayingEvent newMediaPlayingEvent = 6;
        MediaPausedEvent mediaPausedEvent = 7;
        MediaResumedEvent mediaResumedEvent = 8;
    }
}

message NewMediaPlayingEvent {
    Media media = 1;
}

message MediaResumedEvent {
    Aurora.Proto.General.Empty empty = 1;
}

message MediaPausedEvent {
    Aurora.Proto.General.Empty empty = 1;
}

message MemberCreatedEvent {
    Member member = 1;
}

message MemberDeletedEvent {
    string memberName = 1;
}

message EventSubscription {
    EventType type = 2;
}

message ListEventSubscriptionsRequest {
    //Resource name of parent to the subscription list (The member)
    string parent = 1;
    int32 pageSize = 2;
    string pageToken = 3;
}

message ListEventSubscriptionsResponse {
    repeated EventSubscription subscriptions = 1;
}

message CreateEventSubscriptionRequest {
    //Resource name of the parent to the subscription list (The member)
    string parent = 1;
    EventSubscription eventSubscription = 2;
}

message DeleteEventSubscriptionRequest {
    //Resource name of the subscription to delete
    string parent = 1;
    EventType type = 2;
}

message CreateEventSubscriptionListRequest {
    //Resource name of the parent to the subscription list (The member)
    string parent = 1;
    repeated EventSubscription eventSubscriptions = 2;
}

message CreateEventSubscriptionListResponse {
    repeated EventSubscription eventSubscriptions = 1;
}

message DeleteAllEventSubscriptionsRequest {
    //Resource name of the parent to the subscription list (the member)
    string parent = 1;
}

message GetEventsRequest {
    //Resource name of the parent to the event stream (the member)
    string parent = 1;
}