syntax = "proto2";

package wix.api;

import "google/protobuf/descriptor.proto";
import "wix/api/annotations.proto";

option java_multiple_files = true;
option java_outer_classname = "CallbackProto";
option java_package = "com.wix.api";

/*
callback option is used to denote two separate concepts:
1. DomainEvents- these are events your service sends on all activities in your entity. Emitted as a result of this method.
service BlooperService {
   option (wix.api.service_entity).message = "com.wixpress.examples.Blooper"; //the "main" entity
   rpc CreateBlooper (CreateBlooperRequest) returns (CreateBlooperResponse) {
       option (wix.api.callback) = {
           event_type: CREATED
       };
   };
   rpc MissedBlooper (MissedBlooperRequest) returns (MissedBlooperResponse) {
       option (wix.api.callback) = {
           event_type: Action
           payload: "com.wixpress.examples.BlooperWasMissed"
       };
   };
}
message Blooper {
   option (wix.api.entity) = {
       fqdn: "wix.examples.Blooper"
   };
}
message BlooperWasMissed {
    int32 how_funny_it_could_have_been = 1;
}


2. Kafka events that are internal to your domain and that are not related to a specific entity. Emitted as a result of this method.
service BlooperService {
   rpc Update (Request) returns (Response) {
       option (wix.api.callback) = {
           segment: USERS
           topic: "Blooper.Update"
           payload: "BlooperUpdateNotification" //name of the Message that is sent as event
           permission: "Some.Permission" //permission required to consume this event as a webhook
       };
   };
}
*/
extend google.protobuf.MethodOptions {
    repeated Callback callback = 50000;
    repeated Emits emits = 50001;
}

/*
event option is used to denote two separate concepts:
1. DomainEvents- these are events your service sends on all activities in your entity (see examples above)
2. Kafka events that are internal to your domain and that are not related to a specific entity
Both are emitted by the service, not necessarily as a result of a method call (some internal process of the service)
Internal to domain event example:
service BlooperService {
   option (wix.api.event) = {
       segment: PUBLIC
       topic: "Blooper.Update"
       payload: "BlooperUpdateNotification" //name of the Message that is sent as event
       permission: "Some.Permission" //permission required to consume this event as a webhook
   };
   rpc Update (Request) returns (Response) {
       //...
   };
}
*/
extend google.protobuf.ServiceOptions {
    repeated Callback event = 50000;
    repeated CallbackDeprecation event_deprecated = 50001;
    // reserved 50002; TODO(aplus, 2024-08-13) remove when all artifact sync/GA
}

message Callback {
    enum EventType {
        UNKNOWN = 0;
        CREATED = 1;
        UPDATED = 2;
        DELETED = 3;
        ACTION = 4;
    }

    optional string topic = 1;
    optional Segment.SegmentName segment = 8; // currently defaults to "legacy", will be `required` when legacy cluster is removed
    optional string payload = 2;
    optional string permission = 3;  
    optional EventType event_type = 4;
    optional Exposure exposure = 6;
    optional Maturity maturity = 7;
}

message DomainEvent {
    enum EventType {
        UNKNOWN = 0;
        CREATED = 1;
        UPDATED = 2;
        DELETED = 3;
        ACTION = 4;
    }
    optional string action_message_fqn = 2; // Required when event_type == ACTION, otherwise must not be set
    optional string webhook_permission_override = 3;
    optional EventType event_type = 4;
    optional Exposure exposure = 6;
    optional Maturity maturity = 7;
    optional string additional_metadata_fqn = 8;
    optional DomainEventDeprecation deprecated = 9; // assigned and detailed where the subject event is deprecated
}

message Emits {
    required DomainEvent.EventType event_type = 1;
    optional string action_message_fqn = 2; // Required when event_type == ACTION, otherwise must not be set
}

message DomainEventDeprecation {
    optional string replaced_by = 1;
    optional string target_removal_date = 2;
}

message CallbackDeprecation {
    optional string replaced_by = 1;
    optional string target_removal_date = 2;
    optional Callback.EventType event_type = 3;
    optional string custom_slug = 4; // required when event_type=action
    optional string payload = 5;
}

message Segment {

    /**
     * [Segment] annotation registers to Confluent clusters.
     * Existing topics might have a hard-coded segment in Greyhound, so this option is not required in proto.
     * However, new topics must provide a segment, or greyhound will throw an exception.
     * @see https://bo.wix.com/wix-docs/rnd/p13n-guidelines---aips/guidance-aips/design-patterns/[7016]-events#p13n-guidelines---aips_guidance-aips_design-patterns_[7016]-events_12-choose-the-right-segment
     */
    enum SegmentName {
        UNSPECIFIED = 0; // currently means "auto-resolved for old topics", will be forbidden when legacy cluster is removed

        /**
         * For events that are consumed in 42 and uw2 only.
         * This also includes a case where an event is produced from 84/AE1 via toMainDC
         */
        USERS = 1;

        /**
         * For events that are consumed in all DCs.
         * This includes both cases where an event is published from 84/AE1 and cases where it's published from 42/uw2 and replicated via Raven to 84/AE1
         */
        PUBLIC = 2;

        /**
         * For DevEx services/migrations.
         * Deployed on 42, uw2.
         */
        OTHERS = 3;
    }
}

