syntax = "proto3";

package wix.dealerOfferEvents.api.v1;

import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/struct.proto";
import "wix/api/entity.proto";
import "wix/api/annotations.proto";
import "wix/api/validations.proto";
import "wix/common/query.proto";
import "wix/common/paging.proto";

import "wix/dealerOfferEvents/api/v1/event.proto";

option java_package = "com.wix.dealerOfferEvents.api.v1";

service DealerOfferEventsService {
  option (wix.api.service_entity).message = "wix.dealerOfferEvents.api.v1.OfferEvent";
  option (wix.api.service_exposure) = INTERNAL;

  // Report an event for a Dealer Offer for a specific user identity and metasite.
  // required fields: event.type, event.offer_id and event.real_estate_id (placementId) in addition - some of the event types require specific payload.
  // For example MAIN_CTA_CLICK needs to be reported with main_cta_click payload that contains additional data on the event such as target_url.
  // VIEW event does not require any additional information.
  //
  // Identity and metasite are taken implicitly from request by default - NO NEED TO PASS SUCH INFO.
  // If an event is reported from metasite(BM/EDITOR), MAKE SURE request is sent with an authorization header.
  //
  // For some EDGE CASES - privileged apps with DEALER.OFFER_EVENTS_EXPLICIT_CONTEXT can report on behalf of user and fill identity(user_id and msid) fields.
  rpc ReportEvent (ReportEventRequest) returns (ReportEventResponse) {
    option (google.api.http).post = "/v1/dealer-offer-events/{event.offer_id}";

    option (wix.api.required) = "ReportEventRequest.event.offer_id";
    option (wix.api.maturity) = GA;
  };

  // return list of offer events summary for a bulk of offer ids.
  // a summary response contains last event happened for each event type or event counts.
  // - you have to provide field masks for all the event types you want to get for each offer.
  // BY DEFAULT Summaries will be filtered by the implicit identity and metasite in the request.
  //
  // FOR SOME EDGE CASES - special permission DEALER.OFFER_EVENTS_EXPLICIT_CONTEXT is required in order to pass explicit identity and metasite filter.
  //
  // You can request event summary data for specific offers or specific campaigns.
  //
  // In case campaign level events summary requested, cumulative data is returned:
  //      — events counters are a sum of all campaign's offer events counters
  //      — lastEvent for campaign is the lastEvent of the "latest" offer within campaign
  //      — etc.
  //
  //  If summary_filter.placement_id is set, then only offers belonging to campaign & placement is counted
  //  for campaign level summary
  //
  // If offer_ids is empty — you get empty result.events_summary
  // If campaign_ids empty — you get empty result.campaign_events_summary
  //
  rpc ListEventsSummary (ListEventsSummaryRequest) returns (ListEventsSummaryResponse) {
    option (google.api.http).get = "/v1/dealer-offer-events/summary";
    option (wix.api.required) = "ListEventsSummaryRequest.summary_filter.field_mask";
    option (wix.api.maturity) = GA;
  };

  // ONLY SUPPORTED FOR EVENT TYPE AGENT_MARK - USER JOURNEY USE CASES
  // Returns list of offer events for given filters.
  // Filters: offer_id (required), event_type (required, only AGENT_MARK); siteId is taken implicitly
  //  from aspects, so they must be server signed with siteId.
  // Supported `paging`. Events limit by default is 200.
  // Not supported 'sort`, `fields` and `fieldsets`. Events are sorted in descending order by creation_date.
  //
  // Query examples:
  //  query: { filter: { offer_id: <uuid> }, event_type: 'AGENT_MARK'}}
  //  query: { filter: { offer_id: { $in: [<uuid1>, <uuid2>] }, event_type: 'AGENT_MARK'}}
  //  query: { filter: { offer_id: { $in: [<uuid1>, <uuid2>] }, event_type: 'AGENT_MARK'}, paging: { offset: 10, limit: 100 } }
  rpc QueryEvents (QueryEventsRequest) returns (QueryEventsResponse) {

    option (google.api.http).get = "/v1/dealer-offer-events/query";

    option (wix.api.required) = "QueryEventsRequest.query";
    option (wix.api.required) = "QueryEventsRequest.query.filter";
    option (wix.api.maturity) = ALPHA;
  };
}


message ReportEventRequest {
  // Event properties container
  OfferEvent event = 1;

  // Deviant Art specific use-case: signed jwt token with uuid of deviant art user in wix bi infra
  google.protobuf.StringValue deviant_art_user_id = 2 [(.wix.api.maxLength) = 4096];
}

message ReportEventResponse {
}


message ListEventsSummaryRequest {
  // each element in response.eventsSummary is a summary of offerId
  repeated string offer_ids = 1 [(wix.api.format) = GUID];

  // each element in response.campaignEventsSummary is a summary of corresponding campaignId
  repeated string campaign_ids = 3 [(wix.api.format) = GUID];

  // applied to each requested offer or each offer within requested campaigns
  // all fields are optional - if not passing fields mask then no summary will be returned
  SummaryFilter summary_filter = 2;
}

message SummaryFilter {
  // OPNIONAL - only events reported with this user id will be taken into account - supported by AGENT_MARK only
  google.protobuf.StringValue user_id = 1 [(wix.api.format) = GUID];

  // OPNIONAL - only events reported with this account id will be taken into account
  google.protobuf.StringValue target_account_id = 2 [(wix.api.format) = GUID];

  // OPNIONAL - only events reported with this site id will be taken into account
  google.protobuf.StringValue site_id = 3 [(wix.api.format) = GUID];

  reserved 4;

  // which placement offers take into account in campaign scope (applicable only for campaign_ids requests)
  google.protobuf.StringValue placement_id = 6 [(wix.api.format) = GUID];
  // todo: add  (wix.api.referenced_entity) = "wix.dealer.v1.placement"]; when it's on BO API

  // Array of strings that will determine which events will be included in EventsSummary response
  // In the format of EventsSummary fields "<event_usecase>.<event_type>"
  //
  // Possible values for VIEW events:
  //      - lastEvent.VIEW
  //      - eventsCount.VIEW
  // Possible values for MAIN_CTA_CLICK events:
  //  * get last main cta click of any action type:
  //      - lastEvent.MAIN_CTA_CLICK
  //      - eventsCount.MAIN_CTA_CLICK
  //
  // Possible values for AGENT_MARK events:
  //  * get last event of any status:
  //      - lastEvent.AGENT_MARK
  //
  //
  // For example:
  //      "lastEvent.VIEW,lastEvent.AGENT_MARK,eventsCount.MAIN_CTA_CLICK"
  //
  //  will result in (if CLOSE event exists for given offer/user/metasite)
  //      {
  //          lastEvent: {
  //              VIEW: {...(OfferEvent data)},
  //              AGENT_MARK: {...(OfferEvent data)}
  //          },
  //          eventsCount:{ MAIN_CTA_CLICK: { totalCount: 20 }}
  //      }
  //
  google.protobuf.FieldMask field_mask = 5;
}

message EventCounts {
  // counter
  google.protobuf.Int32Value total_count = 1;
}

message EventsSummary {
  // If set - means this summary is about the offer
  google.protobuf.StringValue offer_id = 1 [(wix.api.format) = GUID];
  // todo:  add (wix.api.referenced_entity) = "wix.dealer.v1.backoffice_offer"]; when it's on BO API

  // If set - means this summary is about the campaign
  google.protobuf.StringValue campaign_id = 5 [(wix.api.format) = GUID];
  // todo: add  (wix.api.referenced_entity) = "wix.dealer.v1.campaign"]; when it's on BO API

  // Campaign summary: Last event per type among all offers within campaign (+ placement if filter specified)
  // Offer summary: Last event per type for given offer
  //
  // key is a value from EventType enum
  // OfferEvent enity eill be returned partailly dependeing on event type - see details on entity
  map<string, OfferEvent> last_event = 3;

  // Campaign summary: cumulative counters for all offer events of the same type within this campaign (+ placement if filter specified)
  // Offer summary: event counts per type for given offer
  //
  // key is a value from EventType enum
  map<string, EventCounts> events_count = 10;

  reserved 2, 4;
}

message ListEventsSummaryResponse {
  // list of event summaries for requested offer ids, will be empty if only campaign events requested
  repeated EventsSummary events_summary = 1;

  // list of event summaries for requested campaign ids, will be empty if only offer events requested
  repeated EventsSummary campaign_events_summary = 2;
}

message QueryEventsRequest {
  // Query examples:
  //  query: { filter: { offer_id: <uuid> }, event_type: 'AGENT_MARK'}}
  //  query: { filter: { offer_id: { $in: [<uuid1>, <uuid2>] }, event_type: 'AGENT_MARK'}}
  //  query: { filter: { offer_id: { $in: [<uuid1>, <uuid2>] }, event_type: 'AGENT_MARK'}, paging: { offset: 10, limit: 100 } }
  wix.common.Query query = 1;
}

message QueryEventsResponse {
  // List of offer events
  repeated OfferEvent events = 1;

  // result paging status
  wix.common.PagingMetadata paging_metadata = 2;
}
