syntax = "proto3";

package dcache;

message Level {
    uint32 visitor_threshold = 301;
    uint32 difficulty_factor= 302;
}

message Defense {
    repeated Level levels = 401;
}
message MCaptcha {
	uint64 duration = 502;
	Defense defense = 503;
}

message AddCaptchaRequest {
	string id = 601;
	MCaptcha mcaptcha = 602;
}


message RenameCaptchaRequest {
	string name = 701;
	string rename_to = 702;
}


message CachePowRequest {
	string string= 801;
	uint32 difficulty_factor = 802;
	uint64 duration = 803;
	string key = 804;
}

message CacheResultRequest {
	string token =  817;
	string key = 818;
	uint64 duration= 819;
}

message DeleteCaptchaResultRequest {
	string token = 821;
}

message CaptchaID{
	string id = 1;
}

message PoID{
	string id = 1;
}


message AddVisitorResult {
    uint64 duration = 901;
    uint32 difficulty_factor = 902;
}

message OptionAddVisitorResult {
	optional AddVisitorResult result = 911;
}

message RaftRequest {
  string data = 1;
}

message RaftReply {
  string data = 1;
  string error = 2;
}

message Learner {
    uint64 id = 1;
    string addr = 2;
}


message CaptchaExistsResponse {
    bool exists = 1;
}


message GetVisitorCountResponse {
    uint32 visitors = 1;
}


message OptionGetVisitorCountResponse {
	optional GetVisitorCountResponse result = 1;
}

message DcacheRequest {
    oneof DcacheRequest {
	AddCaptchaRequest addCaptcha = 1;
	CaptchaID addVisitor = 2;
	RenameCaptchaRequest renameCaptcha = 3;
	CaptchaID removeCaptcha = 4;
	CachePowRequest cachePow = 5;
	CacheResultRequest cacheResult = 6;
	CaptchaID captchaExists = 7;
	CaptchaID getVisitorCount = 8;
    }
}


message DcacheResponse {
    oneof DcacheResponse {
		OptionAddVisitorResult option_add_visitor_result = 1;
        RaftReply other = 2;
        CaptchaExistsResponse captcha_exists = 3;
        OptionGetVisitorCountResponse get_visitor_count = 4;
	}
}

message DcacheBatchRequest {
    repeated DcacheRequest requests = 1;
}

message DcacheBatchResponse {
    repeated DcacheResponse responses = 1;
}

message RetrievePowRequest {
    string token = 1;
    string key = 2;
}

message RetrievePowResponse {
    uint32 difficulty_factor = 1;
    uint64 duration = 2;
    string key = 3;
}


message CaptchaResultVerified  {
    bool verified  = 1;
}

message DeletePowRequest {
    string string = 1;
}

message OptionalRetrievePoWResponse {
    optional RetrievePowResponse result = 1;
}

service DcacheService {
	rpc AddCaptcha(AddCaptchaRequest) returns (RaftReply) {}
	rpc AddVisitor(CaptchaID) returns (OptionAddVisitorResult) {}
	rpc RenameCaptcha(RenameCaptchaRequest) returns (RaftReply) {}
	rpc RemoveCaptcha(CaptchaID) returns (RaftReply) {}
	rpc CachePow(CachePowRequest) returns (RaftReply) {}
	rpc RetrievePow(RetrievePowRequest) returns (OptionalRetrievePoWResponse) {}
	rpc DeletePow(DeletePowRequest) returns (RaftReply) {}
	rpc CacheResult(CacheResultRequest) returns (RaftReply) {}
	rpc VerifyCaptchaResult(RetrievePowRequest) returns (CaptchaResultVerified) {}
	rpc DeleteCaptchaResult(DeleteCaptchaResultRequest) returns (RaftReply) {}
	rpc CaptchaExists(CaptchaID) returns (CaptchaExistsResponse) {}
	rpc GetVisitorCount(CaptchaID) returns (OptionGetVisitorCountResponse) {}

	rpc PipelineDcacheOps(DcacheBatchRequest) returns (DcacheBatchResponse) {}


	rpc AddLearner(Learner) returns (RaftReply) {}
	rpc Write(RaftRequest) returns (RaftReply) {}

	/// Forward a request to other
	rpc Forward(RaftRequest) returns (RaftReply) {}

	// raft RPC

	rpc AppendEntries(RaftRequest) returns (RaftReply);
	rpc InstallSnapshot(RaftRequest) returns (RaftReply);
	rpc vote(RaftRequest) returns (RaftReply);
}
