syntax = "proto3";

package raids;
option go_package = "code.justin.tv/live/autohost/rpc/raids";

import "google/protobuf/timestamp.proto";

service Raids {
    // Ends a raid.
    rpc CancelRaidBySourceID(CancelRaidBySourceIDRequest) returns (CancelRaidBySourceIDResponse);

    // Creates a PENDING raid that starts on the given channel, and will end on
    // the given target channel.
    rpc CreateRaid(CreateRaidRequest) returns (CreateRaidResponse);

    // Returns whether a user recently participated in a raid.
    rpc DidUserRecentlyRaidChannel(DidUserRecentlyRaidChannelRequest) returns (DidUserRecentlyRaidChannelResponse);

    // Gets the viewers and creators that participated in a given raid.
    rpc GetRaidParticipants(GetRaidParticipantsRequest) returns (GetRaidParticipantsResponse);

    // Gets a user's raid settings.
    rpc GetRaidSettings(GetRaidSettingsRequest) returns (GetRaidSettingsResponse);

    // Gets channels that we recommend a given user should raid.
    rpc GetRaidTargetRecommendations(GetRaidTargetRecommendationsRequest) returns (GetRaidTargetRecommendationsResponse);

    // Gets the raids that have recently targeted the given channel.
    rpc GetRecentRaids(GetRecentRaidsRequest) returns (GetRecentRaidsResponse);

    // Returns whether a specified raid is currently active. A raid is active once it has been initiated
    // and considered deactive when deleted (by TTL)
    rpc IsRaidValid(IsRaidValidRequest) returns (IsRaidValidResponse);

    // Starts a READY raid (redirecting participants to the target's channel page.)
    rpc StartRaidBySourceID(StartRaidBySourceIDRequest) returns (StartRaidBySourceIDResponse);

    // Records that the given user is participating in the given raid.
    // (Raid participants should get channel points, and should not get ads when they load the target's channel page.)
    rpc JoinRaid(JoinRaidRequest) returns (JoinRaidResponse);

    // Removes the given user from the given raid's participants.
    rpc LeaveRaid(LeaveRaidRequest) returns (LeaveRaidResponse);

    // Updates a user's raid settings.
    rpc UpdateRaidSettings(UpdateRaidSettingsRequest) returns (UpdateRaidSettingsResponse);

    // Records the viewers that participated in a given raid
    rpc RecordViewersForRaid(RecordViewersForRaidRequest) returns (RecordViewersForRaidResponse);
}

message CancelRaidBySourceIDRequest {
    string caller_id = 1;
    string source_id = 2;
}

message CancelRaidBySourceIDResponse {
    enum ErrorCode {
        ERROR_CODE_UNSET = 0;
        // The source channel does not have a pending raid to cancel.
        NO_PENDING_RAID = 1;
    }

    // Info on why canceling the operation failed. It is meant to allow us to represent domain specific
    // failure reasons that can't be directly expressed by the standard Twirp error codes.
    ErrorCode error_code = 1;
    Raid raid = 2;
}

message CreateRaidRequest {
    string caller_id = 1;
    string source_id = 2;
    string target_id = 3;
}

message CreateRaidResponse {
    enum ErrorCode {
        ERROR_CODE_UNSET = 0;
        CANNOT_RAID_YOURSELF = 1;
        // Cannot raid target because the target is invalid, banned, or because of the target's settings.
        CANNOT_RAID_TARGET = 2;
        ALREADY_RAIDING = 3;
        // The source channel has more viewers than we can currently support in a raid.
        TOO_MANY_VIEWERS = 4;
    }

    ErrorCode error_code = 1;
    Raid raid = 2;
    CreateRaidNotices notices = 3;
}

message CreateRaidNotices {
    // The target is only intended for mature audiences (and the source is not).
    bool mature = 1;
    // The target has follower or only subscriber only chat.
    bool restricted_chat = 2;
}

message DidUserRecentlyRaidChannelRequest {
    // We look up the user by their user_id and device_id. The user is expected to tell us that
    // they are participating in a raid by calling JoinRaid with their user_id and device_id.
    string user_id = 1;
    string device_id = 2;
    string target_id = 3;
}

message DidUserRecentlyRaidChannelResponse {
    bool did_user_recently_raid_channel = 1;
}

message GetRecentRaidsRequest {
    string caller_id = 1;
    string target_id = 2;
}

message GetRecentRaidsResponse {
    repeated Raid raids = 1;
}

message IsRaidValidRequest {
    string raid_id = 1;
    string target_channel_id = 2;
}

message IsRaidValidResponse {
    bool valid = 1;
}

message StartRaidBySourceIDRequest {
    string caller_id = 1;
    string source_id = 2;
}

message StartRaidBySourceIDResponse {
    enum ErrorCode {
        ERROR_CODE_UNSET = 0;
        // The source channel does not have a pending raid to start.
        NO_PENDING_RAID = 1;
        // The pending raid is within the 30s period before it can be started.
        RAID_NOT_READY_TO_START = 2;
    }

    // Info on why canceling the operation failed. It is meant to allow us to represent domain specific
    // failure reasons that can't be directly expressed by the standard Twirp error codes.
    ErrorCode error_code = 1;
    Raid raid = 2;
}

message GetRaidParticipantsRequest {
    string raid_id = 1;
}

message GetRaidParticipantsResponse {
    repeated string user_ids = 1;
}

message GetRaidSettingsRequest {
    string caller_id = 1;
    string user_id = 2;
}

message GetRaidSettingsResponse {
    RaidSettings settings = 1;
}

message GetRaidTargetRecommendationsRequest {
    string caller_id = 1;
    string user_id = 2;
}

message GetRaidTargetRecommendationsResponse {
    repeated string target_ids = 1;
}

message JoinRaidRequest {
    string raid_id = 1;

    // The request must include either the participant's user_id, device_id, or both.
    string user_id = 2;
    string device_id = 3;

    // Use no_proxy to indicate that this request should not be proxied.  Only used for the TwitchRaids migration
    bool no_proxy = 4;
}

message RecordViewersForRaidRequest {
    string raid_id = 1;
    string target_id = 2;
}

message JoinRaidResponse {}

message LeaveRaidRequest {
    string raid_id = 1;

    // The request must include either the participant's user_id, device_id, or both.
    string user_id = 2;
    string device_id = 3;

    // Use no_proxy to indicate that this request should not be proxied.  Only used for the TwitchRaids migration
    bool no_proxy = 4;
}

message LeaveRaidResponse {}

message UpdateRaidSettingsRequest {
    // The ID of the user that is making the request. (The authenticated user.)
    string caller_id = 1;
    // The user whose settings should be updated.
    string user_id = 2;
    // The group that is allowed to raid the given user.
    CanBeRaidedBy can_be_raided_by = 3;
}

message UpdateRaidSettingsResponse {
    RaidSettings settings = 1;
}

message RecordViewersForRaidResponse {
    repeated string user_ids = 1;
}

//
// Common models
//

// Raid contains the information about a raid.
message Raid {
    string raid_id = 1;
    // ID of the channel the raid was originated on.
    string source_id = 2;
    // ID of the channel the raid is targeting.
    string target_id = 3;
    // ID of the user that created the raid.
    string creator_id = 4;
    // The time the raid was created.
    google.protobuf.Timestamp created_at = 5;
    // The time the raid was started.
    google.protobuf.Timestamp started_at = 6;
    // The number of users that are participating in the raid.
    int32 participant_count = 7;
}

enum RaidStatus {
    RAID_STATUS_UNSET = 0;

    // PENDING means that the raid was newly created. The raid stays in the PENDING state for
    // a short amount of time to allow viewers to opt in or out. The creator cannot start the
    // raid until it enters the READY state.
    PENDING = 1;

    // READY means that the creator is allowed to start the raid.
    READY = 2;

    // IN_PROGRESS means that the raid is in progress, and participants are being redirected to the
    // target's channel page.
    IN_PROGRESS = 3;

    // ENDED means that the raid has been completed or been canceled.
    ENDED = 4;
}

message RaidSettings {
    CanBeRaidedBy can_be_raided_by = 1;
}

enum CanBeRaidedBy {
    CAN_BE_RAIDED_BY_UNSET = 0;
    CAN_BE_RAIDED_BY_ALL = 1;
    CAN_BE_RAIDED_BY_NETWORK = 2;
    CAN_BE_RAIDED_BY_NONE = 3;
}
