syntax = "proto3";

package lol_core;

message ApplyReq {
    bytes message = 1;
    bool core = 2;
    bool mutation = 3;
}
message ApplyRep {
    bytes message = 1;
}
message CommitReq {
    bytes message = 1;
    bool core = 2;
}
message CommitRep {}
message ProcessReq {
    bytes message = 1;
    bool core = 2;
}
message ProcessRep {
    bytes message = 1;
}
message Entry {
    uint64 term = 1;
    uint64 index = 2;
    bytes command = 3;
}
message AppendStreamHeader {
    string sender_id = 1;
    uint64 prev_log_term = 2;
    uint64 prev_log_index = 3;
}
message AppendStreamEntry {
    uint64 term = 1;
    uint64 index = 2;
    bytes command = 3;
}
message AppendEntryReq {
    oneof elem {
        AppendStreamHeader header = 1;
        AppendStreamEntry entry = 2;
    }
}
message AppendEntryRep {
    bool success = 1;
    uint64 last_log_index = 2;
}
message GetSnapshotReq {
    uint64 index = 1;
}
message GetSnapshotRep {
    bytes chunk = 1;
}
message RequestVoteReq {
    uint64 term = 1;
    string candidate_id = 2;
    uint64 last_log_term = 3;
    uint64 last_log_index = 4;
    bool force_vote = 5;
}
message RequestVoteRep {
    bool vote_granted = 1;
}
message HeartbeatReq {
    uint64 term = 1;
    string leader_id = 2;
    uint64 leader_commit = 3;
}
message HeartbeatRep {}
message TimeoutNowReq {}
message TimeoutNowRep {}
message AddServerReq {
    string id = 1;
}
message AddServerRep {}
message RemoveServerReq {
    string id = 1;
}
message RemoveServerRep {}

service Raft {
    rpc RequestVote (RequestVoteReq) returns (RequestVoteRep);
    rpc SendAppendEntry (stream AppendEntryReq) returns (AppendEntryRep);
    rpc GetSnapshot (GetSnapshotReq) returns (stream GetSnapshotRep);
    rpc RequestApply (ApplyReq) returns (ApplyRep);
    rpc RequestCommit (CommitReq) returns (CommitRep);
    rpc RequestProcess (ProcessReq) returns (ProcessRep);
    rpc RequestProcessLocally (ProcessReq) returns (ProcessRep);
    rpc SendHeartbeat (HeartbeatReq) returns (HeartbeatRep);
    rpc TimeoutNow (TimeoutNowReq) returns (TimeoutNowRep);
    rpc AddServer (AddServerReq) returns (AddServerRep);
    rpc RemoveServer (RemoveServerReq) returns (RemoveServerRep);
}