syntax = "proto3";
option java_package = "io.textile.pb";
option go_package = "go-textile/pb";

import "google/protobuf/timestamp.proto";
import "google/protobuf/struct.proto";
import "message.proto";

// SWARM PEERS //

message SwarmPeerStream {
    string protocol = 1;
}

message SwarmPeer {
    string addr                      = 1;
    string peer                      = 2;
    string latency                   = 3;
    string muxer                     = 4;
    int32 direction                  = 5;
    repeated SwarmPeerStream streams = 6;
}

message SwarmPeerList {
    repeated SwarmPeer peers = 1;
}

// PEERS //

message Peer {
    string id                         = 1;
    string address                    = 2;
    string name                       = 3;
    string avatar                     = 4;
    repeated Cafe inboxes             = 5;
    google.protobuf.Timestamp created = 6;
    google.protobuf.Timestamp updated = 7;
}

message PeerList {
    repeated Peer items = 1;
}

message User {
    string address = 1;
    string name    = 2;
    string avatar  = 3;
}

message Contact {
    string address          = 1;
    string name             = 2;
    string avatar           = 3;
    repeated Peer peers     = 4;
    repeated string threads = 5;
}

message ContactList {
    repeated Contact items = 1;
}

// THREADS //

message Thread {
    string id                 = 1;
    string key                = 2;
    bytes sk                  = 3;
    string name               = 4;
    string schema             = 5;
    string initiator          = 6;
    Type type                 = 7;
    Sharing sharing           = 8;
    repeated string whitelist = 9;
    State state               = 10 [deprecated = true];
    string head               = 11;

    // Type controls read (R), annotate (A), and write (W) access
    enum Type {
        PRIVATE   = 0; // initiator: RAW, whitelist:
        READ_ONLY = 1; // initiator: RAW, whitelist: R
        PUBLIC    = 2; // initiator: RAW, whitelist: RA
        OPEN      = 3; // initiator: RAW, whitelist: RAW
    }

    // Sharing controls if (Y/N) a thread can be shared
    enum Sharing {
        NOT_SHARED  = 0; // initiator: N, whitelist: N
        INVITE_ONLY = 1; // initiator: Y, whitelist: N
        SHARED      = 2; // initiator: Y, whitelist: Y
    }

    // State indicates the loading state
    enum State {
        LOADING_TAIL = 0; // tail blocks are being loaded
        LOADED       = 1; // blocks are all loaded / paused
        LOADING_HEAD = 2; // head block is being loaded
    }

    // view info
    repeated Block head_blocks  = 101;
    Node schema_node            = 102;
    int32 block_count           = 103;
    int32 peer_count            = 104;
}

message ThreadList {
    repeated Thread items = 1;
}

message ThreadPeer {
    string id     = 1;
    string thread = 2;
    bool welcomed = 3;
}

// BLOCKS //

message Block {
    string id                      = 1;
    string thread                  = 2;
    string author                  = 3;
    BlockType type                 = 4;
    google.protobuf.Timestamp date = 5;
    repeated string parents        = 6;
    string target                  = 7;
	string data                    = 9;
    string body                    = 8;
	BlockStatus status             = 10;
	int32 attempts                 = 11;

    enum BlockType {
        MERGE    = 0 [deprecated = true]; // block is stored in plaintext, no payload
        IGNORE   = 1;
        FLAG     = 2;
        JOIN     = 3;
        ANNOUNCE = 4;
        LEAVE    = 5; // no payload
        TEXT     = 6;
        FILES    = 7;
        COMMENT  = 8 [deprecated = true];
        LIKE     = 9;

        ADD = 50;
    }

	enum BlockStatus {
		READY   = 0; // downloaded, also synced if outbound
		QUEUED  = 1; // waiting on sync
		PENDING = 2; // waiting on download
	}

    // view info
    User user = 101;
}

message BlockList {
    repeated Block items = 1;
}

message BlockMessage {
    string id                      = 1;
    string peer                    = 2;
    Envelope env                   = 3;
    google.protobuf.Timestamp date = 4;
}

// INVITES //

message Invite {
    string id                      = 1;
    bytes block                    = 2;
    string name                    = 3;
    Peer inviter                   = 4;
    google.protobuf.Timestamp date = 5;
    repeated string parents        = 6;
}

message InviteList {
    repeated Invite items = 1;
}

// FILES //

message FileIndex {
    string mill                     = 1;
    string checksum                 = 2;
    string source                   = 3;
    string opts                     = 4;
    string hash                     = 5;
    string key                      = 6;
    string media                    = 7;
    string name                     = 8;
    int64 size                      = 9;
    google.protobuf.Timestamp added = 10;
    google.protobuf.Struct meta     = 11;
    repeated string targets         = 12;
}

message Node {
    string name                        = 1;
    bool pin                           = 2;
    bool plaintext                     = 3;
    string mill                        = 4;
    map<string, string> opts           = 5;
    google.protobuf.Struct json_schema = 6;
    map<string, Link> links            = 8;
}

message Link {
    string use                         = 1;
    bool pin                           = 2;
    bool plaintext                     = 3;
    string mill                        = 4;
    map<string, string> opts           = 5;
    google.protobuf.Struct json_schema = 6;
}

// NOTIFICATIONS

message Notification {
    string id                      = 1;
    google.protobuf.Timestamp date = 2;
    string actor                   = 3;
    string subject                 = 4;
    string subject_desc            = 5;
    string block                   = 6;
    string target                  = 7;
    Type type                      = 8;
    string body                    = 9;
    bool read                      = 10;

    enum Type {
        INVITE_RECEIVED     = 0;
        ACCOUNT_PEER_JOINED = 1;
        ACCOUNT_PEER_LEFT   = 8;
        PEER_JOINED         = 2;
        PEER_LEFT           = 3;
        MESSAGE_ADDED       = 4;
        FILES_ADDED         = 5;
        COMMENT_ADDED       = 6;
        LIKE_ADDED          = 7;
    }

    // view info
    User user = 101;
}

message NotificationList {
    repeated Notification items = 1;
}

// CAFE CLIENT //

message Cafe {
    string peer     = 1;
    string address  = 2;
    string api      = 3;
    string protocol = 4;
    string node     = 5;
    string url      = 6;
}

message CafeSession {
    string id                      = 1;
    string access                  = 2;
    google.protobuf.Timestamp exp  = 3;
    string refresh                 = 4;
    google.protobuf.Timestamp rexp = 5;
    string subject                 = 6;
    string type                    = 7;
    Cafe cafe                      = 8;
}

message CafeSessionList {
    repeated CafeSession items = 1;
}

// CAFE HOST //

message CafeRequest {
    string id                      = 1;
    string peer                    = 2;
    string target                  = 3;
    Cafe cafe                      = 4;
    string group                   = 8;
    string sync_group              = 10;
    Type type                      = 5;
    google.protobuf.Timestamp date = 6;
    int64 size                     = 7;
    Status status                  = 9;
    int32 attempts                 = 11;
    int64 group_size               = 12;
    int64 group_transferred        = 13;

    enum Type {
        STORE          = 0;
        UNSTORE        = 3;
        STORE_THREAD   = 1;
        UNSTORE_THREAD = 4;
        INBOX          = 2;
    }

    enum Status {
        NEW      = 0;
        PENDING  = 1;
        COMPLETE = 2;
    }
}

message CafeRequestList {
    repeated CafeRequest items = 1;
}

message CafeSyncGroupStatus {
    string id              = 1; // sync group id

    int32 num_total        = 2;
    int32 num_pending      = 3;
    int32 num_complete     = 4;
    int64 size_total       = 5;
    int64 size_pending     = 6;
    int64 size_complete    = 7;

    int64 groups_size_total    = 8;
    int64 groups_size_complete = 9;

    string error        = 50;
    string error_id     = 51;
}

message CafeHTTPRequest {
    Type type                   = 1;
    string url                  = 2;
    map<string, string> headers = 3;
    string path                 = 4;

    enum Type {
        PUT    = 0;
        POST   = 1;
        DELETE = 2;
    }
}

message CafeMessage {
    string id                      = 1;
    string peer                    = 2;
    google.protobuf.Timestamp date = 3;
    int32 attempts                 = 4;
}

message CafeClientNonce {
    string value                   = 1;
    string address                 = 2;
    google.protobuf.Timestamp date = 3;
}

message CafeClient {
    string id                         = 1;
    string address                    = 2;
    google.protobuf.Timestamp created = 3;
    google.protobuf.Timestamp seen    = 4;
    string token                      = 5;
}

message CafeClientList {
    repeated CafeClient items = 1;
}

message CafeToken {
    string id                      = 1;
    bytes value                    = 2;
    google.protobuf.Timestamp date = 3;
}

message CafeClientThread {
    string id        = 1;
    string client    = 2;
    bytes ciphertext = 3; // encrypted Thread
}

message CafeClientMessage {
    string id                      = 1;
    string peer                    = 2;
    string client                  = 3;
    google.protobuf.Timestamp date = 4;
}

// Bots KV Store //
message BotKV {
    string key                        = 1;
    bytes value                      = 2;
    google.protobuf.Timestamp created = 3;
    google.protobuf.Timestamp updated = 4;
}
