syntax = "proto3";

package photon.imessage.v1;

import "photon/imessage/v1/address_types.proto";
import "photon/imessage/v1/chat_types.proto";
import "google/protobuf/empty.proto";
import "photon/imessage/v1/message_types.proto";
import "photon/imessage/v1/streaming.proto";

option swift_prefix = "PIMsg_";


// ---------------------------------------------------------------------------
// Service
// ---------------------------------------------------------------------------

// Chat-level reads, mutations, and event streams.
service ChatService {

  // Writes
  rpc CreateChat(CreateChatRequest) returns (CreateChatResponse);

  rpc MarkChatRead(MarkChatReadRequest) returns (google.protobuf.Empty);

  rpc SetBackground(SetBackgroundRequest) returns (google.protobuf.Empty);

  rpc RemoveBackground(RemoveBackgroundRequest) returns (google.protobuf.Empty);

  // Pushes the local user's name-and-photo card into the target chat so
  // the recipient sees it in their contact suggestions. No observable
  // local state change.
  rpc ShareContactInfo(ShareContactInfoRequest) returns (google.protobuf.Empty);

  // Transient typing-indicator write. No persisted state.
  rpc SetTyping(SetTypingRequest) returns (google.protobuf.Empty);

  // Reads
  rpc GetChat(GetChatRequest) returns (GetChatResponse);

  rpc GetChatCount(GetChatCountRequest) returns (GetChatCountResponse);

  rpc HasBackground(HasBackgroundRequest) returns (HasBackgroundResponse);

  rpc SubscribeChatEvents(SubscribeChatEventsRequest)
      returns (stream SubscribeChatEventsResponse);

}


// ---------------------------------------------------------------------------
// Writes
// ---------------------------------------------------------------------------

message CreateChatRequest {

  repeated string addresses = 1;

  ChatServiceType service = 2;

  optional CreateChatInitialMessage initial_message = 3;

  optional string client_message_id = 100;

}


message CreateChatInitialMessage {

  string text = 1;

  optional bytes attributed_body = 2;

  optional string effect_id = 3;

  optional string subject = 4;

}


message CreateChatResponse {

  Chat chat = 1;

  optional Message initial_message = 2;

}


message MarkChatReadRequest {

  string chat_guid = 1;

}


message SetBackgroundRequest {

  string chat_guid = 1;

  bytes data = 2;

}


message RemoveBackgroundRequest {

  string chat_guid = 1;

}


message ShareContactInfoRequest {

  string chat_guid = 1;

}


message SetTypingRequest {

  string chat_guid = 1;

  bool is_typing = 2;

}


// ---------------------------------------------------------------------------
// Reads
// ---------------------------------------------------------------------------

message GetChatRequest {

  string chat_guid = 1;

}


message GetChatResponse {

  Chat chat = 1;

}


message GetChatCountRequest {

  bool include_archived = 1;

}


message GetChatCountResponse {

  int64 count = 1;

}


message HasBackgroundRequest {

  string chat_guid = 1;

}


message HasBackgroundResponse {

  bool background_present = 1;

}


// ---------------------------------------------------------------------------
// Streams
// ---------------------------------------------------------------------------

message SubscribeChatEventsRequest {

  // Absent = subscribe to every chat the caller can observe.
  optional string chat_guid = 1;

}


message SubscribeChatEventsResponse {

  // Monotonic global sequence shared with `EventService.CatchUpEvents`
  // and every other `Subscribe*` stream. Absent on heartbeat frames.
  optional uint64 sequence = 1;

  oneof payload {

    ChatChangeEvent chat_changed = 10;

    Heartbeat heartbeat = 99;

  }

}
