syntax = "proto3";

package wix.dealerBackoffice.api.v1;

import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
import "wix/api/callback.proto";

import "wix/api/annotations.proto";
import "wix/api/validations.proto";
import "wix/api/permissions.proto";

import "wix/common/paging.proto";
import "wix/common/query.proto";
import "wix/api/entity.proto";

import "wix/dealerBackoffice/api/v1/managers.proto";

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

// Endpoint for managing dealer campaign (see Campaign entity docs).
service CampaignService {
  option (wix.api.service_entity).message = "wix.dealerBackoffice.api.v1.Campaign";
  option (wix.api.service_maturity) = ALPHA;
  option (wix.api.service_exposure) = INTERNAL;

  // Get campaign by guid.
  rpc GetCampaign (GetCampaignRequest) returns (GetCampaignResponse) {
    option (google.api.http).get = "/v1/dealer/backoffice/campaigns/{campaign_id}";
    option (wix.api.required) = "GetCampaignRequest.campaign_id";
    option (wix.api.permission).name = "DEALER_BACKOFFICE.READ_CAMPAIGN";
    option (wix.api.crud) = {
      method: GET_ITEM
      get_options: {
        id_field: "campaign_id"
      }
    };
  }

  // Get multiple campaigns in single request.
  rpc GetCampaignsBulk (GetCampaignsBulkRequest) returns (GetCampaignsBulkResponse) {
    option (google.api.http).get = "/v1/dealer/backoffice/campaigns/bulk";
    option (wix.api.required) = "GetCampaignsBulkRequest.campaign_ids";
    option (wix.api.permission).name = "DEALER_BACKOFFICE.READ_CAMPAIGN";
  }

  // Listing campaigns with Query filters/paging support.
  // Query params supported only partially.
  // See comments to ListCampaignsRequest message.
  rpc QueryCampaigns (QueryCampaignsRequest) returns (QueryCampaignsResponse) {
    option (google.api.http).post = "/v1/dealer/backoffice/campaigns/query";
    option (wix.api.permission).name = "DEALER_BACKOFFICE.READ_CAMPAIGN";
  }

  // Creating new campaign in dealer BO.
  //flynt-disable required-annotation-breaking-change
  rpc CreateCampaign (CreateCampaignRequest) returns (CreateCampaignResponse) {
    option (google.api.http).post = "/v1/dealer/backoffice/campaigns";
    option (wix.api.required) = "CreateCampaignRequest.campaign.name";
    option (wix.api.required) = "CreateCampaignRequest.campaign.product_id";
    option (wix.api.required) = "CreateCampaignRequest.campaign.kpi_id";
    option (wix.api.permission).name = "DEALER_BACKOFFICE.CREATE_CAMPAIGN";
    option (wix.api.crud) = {
      method: CREATE
      create_options: {
        item_field: "campaign"
      }
    };
    option (wix.api.callback) = {
      event_type: CREATED
    };
  }

  // Full update a campaign. Fields that are not set will be overwritten with empty values.
  //flynt-disable required-annotation-breaking-change
  rpc UpdateCampaign (UpdateCampaignRequest) returns (UpdateCampaignResponse) {
    option (google.api.http).put = "/v1/dealer/backoffice/campaigns/{campaign.guid}";
    option (wix.api.required) = "UpdateCampaignRequest.campaign.guid";
    option (wix.api.required) = "UpdateCampaignRequest.campaign.name";
    option (wix.api.required) = "UpdateCampaignRequest.campaign.product_id";
    option (wix.api.required) = "UpdateCampaignRequest.campaign.kpi_id";
    option (wix.api.permission).name = "DEALER_BACKOFFICE.UPDATE_CAMPAIGN";
  }

  // Bring campaign to active state.
  rpc ActivateCampaign (StatusCampaignRequest) returns (StatusCampaignResponse) {
    option (google.api.http).post = "/v1/dealer/backoffice/campaigns/{campaign_id}/activate";
    option (wix.api.required) = "StatusCampaignRequest.campaign_id";
    option (wix.api.permission).name = "DEALER_BACKOFFICE.UPDATE_CAMPAIGN";
  }

  // Bring campaign to inactive state.
  rpc DeactivateCampaign (StatusCampaignRequest) returns (StatusCampaignResponse) {
    option (google.api.http).post = "/v1/dealer/backoffice/campaigns/{campaign_id}/deactivate";
    option (wix.api.required) = "StatusCampaignRequest.campaign_id";
    option (wix.api.permission).name = "DEALER_BACKOFFICE.UPDATE_CAMPAIGN";
  }

  // Bring campaign to archived state.
  rpc ArchiveCampaign (StatusCampaignRequest) returns (StatusCampaignResponse) {
    option (google.api.http).post = "/v1/dealer/backoffice/campaigns/{campaign_id}/archive";
    option (wix.api.required) = "StatusCampaignRequest.campaign_id";
    option (wix.api.permission).name = "DEALER_BACKOFFICE.UPDATE_CAMPAIGN";
  }
}


// Campaign guid container for all status updating endpoints.
message StatusCampaignRequest {
  // Which campaign to update status
  string campaign_id = 1 [(wix.api.format) = GUID];
}

message StatusCampaignResponse {
  // Current campaign calculated status after status update action
  CampaignStatusEnum.Status status = 1 [(wix.api.readOnly) = true];
}

// Update campaign data wrapper
message UpdateCampaignRequest {
  // Campaign properties to be used to update entity
  Campaign campaign = 1;
}

// Update campaign result data wrapper
message UpdateCampaignResponse {
  // Updated campaign with all actual field set up
  Campaign campaign = 1;
}

// Create campaign data wrapper
message CreateCampaignRequest {
  // Campaign properties to be used for new entity
  Campaign campaign = 1;
}

// Update campaign result data wrapper
message CreateCampaignResponse {
  // Created campaign with all actual field set up
  Campaign campaign = 1;
}

// Filtering by status only. Only $in operand supported.
// https://bo.wix.com/wix-docs/rnd/platformization-guidelines/api-query-language#platformization-guidelines_api-query-language_the-filter-section
//
// Examples of valid iputs:
//     query: { filter: { status: 1 }}
//     query: { filter: { status: {$in: [1, 2]} }}
//     query: { filter: { status: {$in: [4, 5]} }},
//              sort: [{ fieldName: 'createdBy', order: 'DESC' }] }
//
// Status values are integers, correspongind to this proto api object:
//        message CampaignStatusEnum {
//            enum Status {
//                UNKNOWN = 0;
//                INACTIVE = 1;
//                ACTIVE = 2;
//                PENDING = 3;
//                FINISHED = 4;
//                ARCHIVED = 5;
//            }
//        }
//
// Only 1 sorting field is supported (first one in array is taken).
// No fields, fieldsets support yet.
//
// Supported fieldNames to sort by:
//    - name
//    - status (TBD)
//    - createdDate
//    - updatedDate
//    - createdBy
//
// TBD:
// query: { filter: { createdBy: '<uuid>' }}
// query: { filter: { createdBy: ['<uuid1>', '<uuid2>'] }}
// query: { filter: { createdBy: '<uuid>', status: 'ARCHIVED' }
message QueryCampaignsRequest {
  wix.common.Query query = 1;
}

// Query results wrapper
message QueryCampaignsResponse {
  // List of campaigns returned
  repeated Campaign campaigns = 1;

  // Paging info of the result set
  wix.common.PagingMetadata paging_metadata = 2;
}

// Single campaign request
message GetCampaignRequest {
  string campaign_id = 1 [(wix.api.format) = GUID];
}

// Single campaign result wrapper
message GetCampaignResponse {
  Campaign campaign = 1;
}

// Multi campaign bulk request
message GetCampaignsBulkRequest {
  repeated string campaign_ids = 1 [(wix.api.format) = GUID];
}

// Multi campaign bulk result wrapper
message GetCampaignsBulkResponse {
  repeated Campaign campaigns = 1;
}

// Campaign is an abstract container for multiple dealer entities united by some arbitrary property
// (advertising campaign, purpose, usecase etc).
// Offers from different placements may belong to same campaign.
message Campaign {
  option (wix.api.entity) = {fqdn:"wix.dealer.v1.campaign", segment: USERS};
  // Unique guid.
  // If empty on creating campaign - assigned by server at the moment of the request
  // If set on creating campaign - will be used, or GRPC exception returned if already exists
  google.protobuf.StringValue guid = 1 [(wix.api.format) = GUID, (wix.api.readOnly) = true];

  // Who created the campaign (wix user guid).
  // Ignored when creating/updating campaign - set by server.
  google.protobuf.StringValue created_by = 2 [(wix.api.format) = GUID, (wix.api.readOnly) = true];

  // Who updated the campaign last.
  // Ignored when creating/updating campaign - set by server.
  google.protobuf.StringValue updated_by = 3 [(wix.api.format) = GUID, (wix.api.readOnly) = true];

  // When the campaign was created.
  // Ignored when creating/updating campaign - set by server.
  google.protobuf.Timestamp created_date = 4 [(wix.api.readOnly) = true];

  // When the campaign was last time updated.
  // Ignored when creating/updating new campaign - set by server.
  google.protobuf.Timestamp updated_date = 5 [(wix.api.readOnly) = true];

  // Human readable name for the campaign. Required.
  string name = 6 [(wix.api.minLength) = 1];

  // State machine is:
  //  Inactive -> Active -> Archived
  //
  // Explicit state changing actions:
  //
  // activate (* -> active)
  // deactivate (* -> inactive)
  // archive (* -> archived)
  CampaignStatusEnum.Status status = 7 [(wix.api.readOnly) = true];

  // product_id is a group of campaigns,  each campaign belong to product_id
  // Required
  string product_id = 8 [(wix.api.minLength) = 1];

  // kpi id from wix bi bank https://bo.wix.com/wix-docs/rest/drafts/bibank
  google.protobuf.StringValue kpi_id = 9 [(wix.api.format) = GUID];

  // Who are the campaign's managers (wix user guids).
  ManagerIdsWrapper managers_ids = 10;
}


message CampaignStatusEnum {
  enum Status {
    UNKNOWN = 0;
    INACTIVE = 1;
    ACTIVE = 2;
    ARCHIVED = 3;
  }
}
