syntax = "proto3";

package grpc;

message Response {
    Client sender = 1;
    string response = 2;
}

enum StatusType {
  LOG = 0;
  MODEL_UPDATE_REQUEST = 1;
  MODEL_UPDATE = 2;
  MODEL_VALIDATION_REQUEST = 3;
  MODEL_VALIDATION = 4;
  INFERENCE = 5;
}

message Status {
    Client sender = 1;
    string status = 2;

    enum LogLevel {
      INFO  = 0;
      DEBUG = 1;
      WARNING = 2;
      ERROR = 3;
      AUDIT = 4;
    }

    LogLevel log_level = 3;
    string data = 4;
    string correlation_id = 5;
    string timestamp = 6;
    StatusType type = 7;
    string extra = 8;

}

enum Channel {
  DEFAULT = 0;
  MODEL_UPDATE_REQUESTS = 1;
  MODEL_UPDATES = 2;
  MODEL_VALIDATION_REQUESTS = 3;
  MODEL_VALIDATIONS = 4;
  STATUS = 5; 
}

message ModelUpdateRequest {
  Client sender = 1;
  Client receiver = 2;
  string model_id = 3;
  string data = 4;
  string correlation_id = 5;
  string timestamp = 6;
  string meta = 7;
}

message ModelUpdate {
  Client sender = 1;
  Client receiver = 2;
  string model_id = 3;
  string model_update_id = 4;
  string correlation_id = 5;
  string timestamp = 6;
  string meta = 7;
}

message ModelValidationRequest {
  Client sender = 1;
  Client receiver = 2;
  string model_id = 3;
  string data = 4;
  string correlation_id = 5;
  string timestamp = 6; 
  string meta = 7;
  bool is_inference = 8;
}

message ModelValidation {
  Client sender = 1;
  Client receiver = 2;
  string model_id = 3;
  string data = 4;
  string correlation_id = 5;
  string timestamp = 6;
  string meta = 7;
}

enum ModelStatus {
  OK = 0;
  IN_PROGRESS = 1;
  IN_PROGRESS_OK = 2;
  FAILED = 3;
}

message ModelRequest {
  Client sender = 1;
  Client receiver = 2;
  bytes data = 3;
  string id = 4;
  ModelStatus status = 5;
}

message ModelResponse {
  bytes data = 1;
  string id = 2;
  ModelStatus status = 3;
  string message = 4;
}

service ModelService {
  rpc Upload(stream ModelRequest) returns (ModelResponse);
  rpc Download(ModelRequest) returns (stream ModelResponse);
}


message GetGlobalModelRequest {
  Client sender = 1;
  Client receiver = 2;
}

message GetGlobalModelResponse {
  Client sender = 1;
  Client receiver = 2;
  string model_id = 3;
}

message Heartbeat {
  Client sender = 1;
}

message ClientAvailableMessage {
  Client sender = 1;
  string data = 2;
  string timestamp = 3;
}

message ListClientsRequest {
  Client sender = 1;
  Channel channel = 2;
}

message ClientList {
  repeated Client client = 1;
}

enum Role {
  WORKER = 0;
  COMBINER = 1;
  REDUCER = 2;
  OTHER = 3;
}

message Client {
  Role role = 1;
  string name = 2;
}

message ReassignRequest {
  Client sender = 1;
  Client receiver = 2;
  string server = 3 ;
  uint32 port = 4;

}

message ReconnectRequest {
  Client sender = 1;
  Client receiver = 2;
  uint32 reconnect = 3 ;
}

enum Command {
  IDLE = 0;
  START = 1;
  PAUSE = 2;
  STOP = 3;
  RESET = 4;
  REPORT = 5;
}

message Parameter {
  string key = 1;
  string value = 2;
}

message ControlRequest {
  Command command = 1;
  repeated Parameter parameter = 2;
}

message ControlResponse {
  string message = 1;
  repeated Parameter parameter = 2;
}

service Control {
  rpc Start(ControlRequest) returns (ControlResponse);
  rpc Stop(ControlRequest) returns (ControlResponse);
  rpc FlushAggregationQueue(ControlRequest) returns (ControlResponse);
}

service Reducer {
  rpc GetGlobalModel (GetGlobalModelRequest) returns (GetGlobalModelResponse);
}

message ConnectionRequest {

}

enum ConnectionStatus {
  NOT_ACCEPTING = 0;
  ACCEPTING = 1;
  TRY_AGAIN_LATER = 2;
}

message ConnectionResponse {
  ConnectionStatus status = 1;
}

service Connector {
    // Stream endpoint for status updates
    rpc AllianceStatusStream (ClientAvailableMessage) returns (stream Status);

    // Report endpoint
    rpc SendStatus (Status) returns (Response);
//    rpc RegisterClient (ClientAvailableMessage) returns (Response);
    // List active clients endpoint
    rpc ListActiveClients (ListClientsRequest) returns (ClientList);

    rpc AcceptingClients (ConnectionRequest) returns (ConnectionResponse);

    // Client messaging to stay engaged.
    rpc SendHeartbeat (Heartbeat) returns (Response);

    rpc ReassignClient (ReassignRequest) returns (Response);
    rpc ReconnectClient (ReconnectRequest) returns (Response);
}

service Combiner {

    // Stream endpoints for training/validation pub/sub
    rpc ModelUpdateRequestStream (ClientAvailableMessage) returns (stream ModelUpdateRequest);
    rpc ModelUpdateStream (ClientAvailableMessage) returns (stream ModelUpdate);
    rpc ModelValidationRequestStream (ClientAvailableMessage) returns (stream ModelValidationRequest);
    rpc ModelValidationStream (ClientAvailableMessage) returns (stream ModelValidation);

    rpc SendModelUpdate (ModelUpdate) returns (Response);
    rpc SendModelValidation (ModelValidation) returns (Response);

}

