syntax = "proto3";

import "google/protobuf/empty.proto";

package code.justin.tv.feeds.following.followsrpc;
option go_package = "followsrpc";

service Follows {

	// GetFollow loads data about a user following a target user
	rpc GetFollow (FollowReq) returns (FollowResp) {}

	// GetBatchFollow loads data about a user following a list of users
	// Invalid targetUserIDs are ignored and not included in the response
	rpc GetBatchFollows (BatchFollowsReq) returns (BatchFollowsResp) {}

	// ListFollows loads data about users followed by user_id
	rpc ListFollows (FollowsReq) returns (FollowsResp) {}

	// ListFollowers loads data about users that are following user_id
	rpc ListFollowers (FollowsReq) returns (FollowsResp) {}

	// CountFollows counts users followed by user_id.
	// If the user does not exist, the count is zero (does not return NotFound errors).
	rpc CountFollows (UserIDReq) returns (CountResp) {}

	// CountFollowers returns the total number of users that are following user_id.
	// If the user does not exist, the count is zero (does not return NotFound errors).
	rpc CountFollowers (UserIDReq) returns (CountResp) {}

	// BatchCountFollowers returns a list of follower count for every user.
	// If the user does not exist, the count is zero for that entry (does not return NotFound errors).
	rpc BatchCountFollowers (UserIDsReq) returns (BatchCountsResp) {}

	// UpsertFollow creates or updates a follow relationship between from_user_id and target_user_id.
	// If the follow doesn't exist and a user has hit their follow limit, a ResourceExhausted error will be returned.
	rpc UpsertFollow (UpsertFollowReq) returns (FollowResp) {}

	// DeleteFollow deletes a follow relationship between from_user_id and target_user_id. It returns the deleted follow.
	// DeleteFollow will return a NotFound error if a follow is not found between from_user_id and target_user_id.
	rpc DeleteFollow (FollowReq) returns (FollowResp) {}

	// HideAllFollows hides all followers and follows related to a user
	rpc HideAllFollows (UserIDReq) returns (google.protobuf.Empty) {}

	// RestoreAllFollows restores all hidden followers and follows related to a user
	rpc RestoreAllFollows (UserIDReq) returns (google.protobuf.Empty) {}
}

message FollowReq {
	string from_user_id = 1;
	string target_user_id = 2;
}

message BatchFollowsReq {
	string from_user_id = 1;
	repeated string target_user_ids = 2;
}

message FollowResp {
	string from_user_id = 1;
	string target_user_id = 2;

	string followed_at = 3; // RFC3399 time
	bool block_notifications = 4;

	string cursor = 5;
}

message FollowsReq {
	string user_id = 1; // user that follows or is followed

	int32 limit = 3; // (default 20) can not be negative
	string cursor = 4;
	int32 offset = 5; // for backwards compatibility

	enum SortDir { ASC = 0; DESC = 1; }
	SortDir order_by_followed_at = 6; // results are sorted by followed_at (descending by default)
}

message BatchFollowsResp {
	repeated FollowResp follows = 1;
}

message FollowsResp {
	repeated FollowResp follows = 1;

	string cursor = 3;
}

message UserIDReq {
	string user_id = 1; // required
}

message CountResp {
	int32 count = 1;
}

message UpsertFollowReq {
	string from_user_id = 1; // required
	string target_user_id = 2; // required
	bool block_notifications = 3;
}

message UserIDsReq {
	repeated string user_ids = 1;
}

message BatchCountResp {
	int32 count = 1;
	string user_id = 2;
}

message BatchCountsResp {
	repeated BatchCountResp counts = 1;
}
