package signalservice;


message Envelope {

  enum Type {
    SESSION_MESSAGE = 6;
    CLOSED_GROUP_MESSAGE = 7;
  }

  // @required
  required Type   type            = 1;
  optional string source          = 2;
  // @required
  required uint64 timestamp       = 5;
  optional bytes  content         = 8;
}

message TypingMessage {
    enum Action {
        STARTED = 0;
        STOPPED = 1;
    }
    // @required
    required uint64 timestamp = 1;
    // @required
    required Action action    = 2;
}


message Unsend {
  // @required
  required uint64 timestamp = 1;
  // @required
  required string author    = 2;
}

message MessageRequestResponse {
  // @required
  required bool isApproved = 1;
}

message Content {
  optional DataMessage                dataMessage                = 1;
  optional CallMessage                callMessage                = 3;
  optional ReceiptMessage             receiptMessage             = 5;
  optional TypingMessage              typingMessage              = 6;
  optional ConfigurationMessage       configurationMessage       = 7;
  optional DataExtractionNotification dataExtractionNotification = 8;
  optional Unsend                     unsendMessage              = 9;
  optional MessageRequestResponse     messageRequestResponse     = 10;
}

message KeyPair {
  // @required
  required bytes publicKey  = 1;
  // @required
  required bytes privateKey = 2;
}

message DataExtractionNotification {

  enum Type {
    SCREENSHOT  = 1; // no way to know this on Desktop
    MEDIA_SAVED = 2; // timestamp
  }

  // @required
  required Type   type      = 1;
  optional uint64 timestamp = 2;
}

message DataMessage {

  enum Flags {
    EXPIRATION_TIMER_UPDATE   = 2;
  }

  message Reaction {
    enum Action {
        REACT = 0;
        REMOVE = 1;
    }
    // @required
    required uint64 id        = 1; // Message timestamp
    // @required
    required string author    = 2;
    optional string emoji     = 3;
    // @required
    required Action action    = 4;
  }

  message Quote {

    message QuotedAttachment {
      optional string            contentType = 1;
      optional string            fileName    = 2;
      optional AttachmentPointer thumbnail   = 3;
    }

    // @required
    required uint64           id          = 1;
    // @required
    required string           author      = 2;
    optional string           text        = 3;
    repeated QuotedAttachment attachments = 4;
  }

  message Preview {
    // @required
    required string            url   = 1;
    optional string            title = 2;
    optional AttachmentPointer image = 3;
  }

  message LokiProfile {
    optional string displayName = 1;
    optional string profilePicture = 2;
  }

  message OpenGroupInvitation {
    // @required
    required string url = 1;
    // @required
    required string name = 3;
  }

  message ClosedGroupControlMessage {

	  enum Type {
	    NEW                           = 1; // publicKey, name, encryptionKeyPair, members, admins, expireTimer
      ENCRYPTION_KEY_PAIR           = 3; // publicKey, wrappers
      NAME_CHANGE                   = 4; // name
      MEMBERS_ADDED                 = 5; // members
      MEMBERS_REMOVED               = 6; // members
      MEMBER_LEFT                   = 7;
      ENCRYPTION_KEY_PAIR_REQUEST   = 8;
	  }



	  message KeyPairWrapper {
	    // @required
	    required bytes publicKey        = 1; // The public key of the user the key pair is meant for
	    // @required
	    required bytes encryptedKeyPair = 2; // The encrypted key pair
	  }

	  // @required
	  required Type           type              = 1;
	  optional bytes          publicKey         = 2;
	  optional string         name              = 3;
	  optional KeyPair        encryptionKeyPair = 4;
	  repeated bytes          members           = 5;
	  repeated bytes          admins            = 6;
	  repeated KeyPairWrapper wrappers          = 7;
    optional uint32         expireTimer       = 8;
	}


  optional string                    body                      = 1;
  repeated AttachmentPointer         attachments               = 2;
  optional GroupContext              group                     = 3;
  optional uint32                    flags                     = 4;
  optional uint32                    expireTimer               = 5;
  optional bytes                     profileKey                = 6;
  optional uint64                    timestamp                 = 7;
  optional Quote                     quote                     = 8;
  repeated Preview                   preview                   = 10;
  optional Reaction                  reaction                  = 11;
  optional LokiProfile               profile                   = 101;
  optional OpenGroupInvitation       openGroupInvitation       = 102;
  optional ClosedGroupControlMessage closedGroupControlMessage = 104;
  optional string                    syncTarget                = 105;
}

message CallMessage {

  enum Type {
    PRE_OFFER          = 6;
    OFFER              = 1;
    ANSWER             = 2;
    PROVISIONAL_ANSWER = 3;
    ICE_CANDIDATES     = 4;
    END_CALL           = 5;
  }

  // @required
  required Type type              = 1;
  repeated string sdps            = 2;
  repeated uint32 sdpMLineIndexes = 3;
  repeated string sdpMids         = 4;

  // @required
  required string uuid            = 5;

}

message ConfigurationMessage {

  message ClosedGroup {
    optional bytes   publicKey         = 1;
    optional string  name              = 2;
    optional KeyPair encryptionKeyPair = 3;
    repeated bytes   members           = 4;
    repeated bytes   admins            = 5;
  }

  message Contact {
    // @required
    required bytes  publicKey         = 1;
    // @required
    required string name              = 2;
    optional string profilePicture    = 3;
    optional bytes  profileKey        = 4;
    optional bool   isApproved        = 5;
    optional bool   isBlocked         = 6;
    optional bool   didApproveMe      = 7;
  }

  repeated ClosedGroup closedGroups    = 1;
  repeated string      openGroups      = 2;
  optional string      displayName     = 3;
  optional string      profilePicture  = 4;
  optional bytes       profileKey      = 5;
  repeated Contact     contacts        = 6;
}

message ReceiptMessage {

  enum Type {
    READ     = 1;
  }

  // @required
  required Type   type      = 1;
  repeated uint64 timestamp = 2;
}

message AttachmentPointer {

  enum Flags {
    VOICE_MESSAGE = 1;
  }

  // @required
  required fixed64 id          = 1;
  optional string  contentType = 2;
  optional bytes   key         = 3;
  optional uint32  size        = 4;
  optional bytes   digest      = 6;
  optional string  fileName    = 7;
  optional uint32  flags       = 8;
  optional uint32  width       = 9;
  optional uint32  height      = 10;
  optional string  caption     = 11;
  optional string  url         = 101;
}

message GroupContext {

  enum Type {
    UNKNOWN      = 0;
    UPDATE       = 1;
    DELIVER      = 2;
    QUIT         = 3;
    REQUEST_INFO = 4;
  }

  // @required
  optional bytes             id      = 1;
  // @required
  optional Type              type    = 2;
  optional string            name    = 3;
  repeated string            members = 4;
  optional AttachmentPointer avatar  = 5;
  repeated string            admins  = 6;
}