syntax = "proto3";

package wix.dealerBackoffice.api.v1;

import "google/protobuf/wrappers.proto";
import "google/protobuf/struct.proto";
import "wix/api/validations.proto";

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

// Entity, holding criteria(s) (rules or filters) for dealer runtime rule engine.
// The rule engine decides if each offer is available to a user or not based on executing these rules
// in real time.
//
// Generally it's a rule engine rules tree structure referencing itself. Actual structure depends on UI constraints.
//
// Optional execution_result field for each filter in the tree holds current rule execution results.
// It's not empty only for offers coming from debug endpoints.
message Targeting {
  // optional current targeting filter execution result (may be set in debug response)
  ExecutionResult execution_result = 1;

  // Type of the criteria (criteria filter)
  CriteriaType type = 2;

  // Client usecase specific current targeting filter label. For example "v2" for root level targeting of
  // V2 targeting offers. Or "basic.geo" for V2 targeting GEO filter.
  google.protobuf.StringValue label = 3;

  // If `true` this targeting result is NOT(criteria result)
  google.protobuf.BoolValue negate = 4;

  // Specific criteria message, according to CriteriaType.
  // Each criteria including top level criteria is a rule for dealer rule engine
  // to execute and get result (true — request does satisfy the criteria, false — does not).
  //
  // Different criteria types represent different kind of rules.
  // For example UserRoleCriteria checks if user is owner of metasite or not,
  // geo criteria checks user location geo etc.
  oneof criteria {
    CompoundCriteria compound = 11;
    CustomFilterCriteria custom_filter = 12;
    ListCriteria geo = 13;
    ListCriteria language = 14;
    UserRoleCriteria user_role = 15;
    UserStatusCriteria user_status = 16; // deprecated
    ListCriteria user_colors = 17; // deprecated
    ListCriteria user_guids = 18;
    ListCriteria template_guids = 19; // deprecated
    ListCriteria post_reg = 20; // deprecated
    ConnectedDomainCriteria connected_domain = 21;
    PremiumPlanCriteria premium_plan = 22;
    google.protobuf.BoolValue exclude_in_sale = 23; // deprecated
    MailboxCriteria mailbox = 24;
    ListCriteria connected_offering_group = 25;
    ListCriteria installed_apps = 26;
    ListCriteria product_groups = 27;
    DomainLengthCriteria domain_length = 28; // deprecated
    ListCriteria mailbox_sale = 29;
    ListCriteria vouchers = 30;
    FreeSiteCriteria free_site = 31; // deprecated
    BrandsCriteria brand = 32;
    // petri spec conducted on runtime and determines if the offer will be retuned to the end user
    // the spec is conducted only after the user was eligable for all targeting rules
    ExperimentCriteria experiment = 34;
    CustomParamCriteria custom_param = 35;
    ListCriteria audience = 36;
    PremiumLandingTabCriteria premium_landing_tab = 37;
    PremiumAccountCriteria premium_account = 38;
    EligibleForSaleCriteria eligible_for_sale = 39;
    ExternalCriteria external_criteria = 40;
    SiteTypeCriteria site_type = 41;
  }

  // removed SavedAudience criteria:
  reserved 33;

  enum CriteriaType {
    UNKNOWN = 0;
    COMPOUND = 11;
    CUSTOM = 12;
    GEO = 13;
    LANGUAGE = 14;
    USER_ROLE = 15;
    USER_STATUS = 16;
    USER_COLORS = 17;
    USER_GUIDS = 18;
    TEMPLATE_GUIDS = 19;
    POST_REG = 20;
    CONNECTED_DOMAIN = 21;
    PREMIUM_PLAN = 22;
    EXCLUDE_IN_SALE = 23;
    MAILBOX = 24;
    CONNECTED_OFFERING_GROUP = 25;
    INSTALLED_APPS = 26;
    PRODUCT_GROUPS = 27;
    DOMAIN_LENGTH = 28;
    MAILBOX_SALE = 29;
    VOUCHERS = 30;
    FREE_SITE = 31;
    BRAND = 32;
    reserved 33;
    reserved "SAVED_AUDIENCE";
    EXPERIMENT = 34;
    CUSTOM_PARAM = 35;
    AUDIENCE = 36;
    PREMIUM_LANDING_TAB = 37;
    PREMIUM_ACCOUNT = 38;
    ELIGIBLE_FOR_SALE = 39;
    EXTERNAL_CRITERIA = 40;
    SITE_TYPE_CRITERIA = 41;
  }
}

// Aggregate criteria for AND/OR tree like structures
message CompoundCriteria {
  enum Operator {
    UNKNOWN = 0;
    OR = 1;
    AND = 2;
  }

  Operator operator = 1;
  repeated Targeting children = 2;
}

// Criteria for targeting rules based on profile service data
message CustomFilterCriteria {
  enum CustomFilterDataSource {
    UNKNOWN = 0;
    USER_PROFILE = 1;
    SITE_PROFILE = 2;
    ACCOUNT_PROFILE = 3;
  }

  string field_id = 1;
  CustomFilterDataSource data_source = 2;
  CustomFilterOperator operator = 3;
  CustomFilterOperator list_restriction = 4;
}

// BI profile filter operator
message CustomFilterOperator {
  message OperatorValueType {
    enum Enum {
      UNKNOWN = 0;
      NUMBER = 1;
      STRING = 2;
      LIST = 3;
      TIMESTAMP = 4;
      BOOLEAN = 5;
    }
  }

  message ComparatorType {
    enum Enum {
      UNKNOWN = 0;
      EQUAL = 1;
      CONTAINED_IN = 2;
      CONTAINS_SOME = 3;
      CONTAINS_NONE = 4;
      NOT_CONTAINS = 5;
      NOT_CONTAINED_IN = 6;
      BE_NOTHING = 7;
      EXISTS = 8;
      MORE_THAN_DAYS = 9;
      WITHIN_DAYS = 10;
      LESS = 11;
      LESS_EQUAL = 12;
      GREATER = 13;
      GREATER_EQUAL = 14;
      SIZE_LESS_EQUAL = 15;
      SIZE_GREATER_EQUAL = 16;
      NOT_EQUAL = 17;
    }
  }

  // BI field data type
  OperatorValueType.Enum value_type = 1;

  // Expected value to be found in BI profile
  google.protobuf.StringValue expected_value = 2 [(.wix.api.maxLength) = 2000];

  // Comparator to apply to value (i.e. if BI value EQUALS, LESS, GREATER than expected value etc.)
  ComparatorType.Enum comparator = 3;
}

// DEPRECATED, use Targeting.label instead
message CriteriaMetaData{
  string label = 1;
}

// Generic filter for list of included/excluded values
message ListCriteria {
  repeated string values = 1;
  bool included = 2;
}

// Filter for targeting based on premium plan eligibility
message PremiumPlanCriteria {
  enum Plan {
    UNKNOWN = 0;
    PREMIUM = 2;
    NONE = 3;
  }

  repeated int32 products = 1;
  Plan plan = 2;
}

// Filter for metasite ownership rules
message UserRoleCriteria {
  enum Enum {
    UNKNOWN = 0;
    OWNER = 2;
    NOT_OWNER = 3;
  }

  Enum value = 1;
}

message PremiumLandingTabCriteria {
  enum Enum {
    UNKNOWN = 0;
    WEBSITE = 1;
    BUSINESS = 2;
  }

  Enum value = 1;
}

// Filter for metasite domain validations
message ConnectedDomainCriteria {
  enum Enum {
    UNKNOWN = 0;
    CONNECTED = 2;
    NOT_CONNECTED = 3;
  }

  Enum value = 1;
}

message MailboxCriteria {
  enum Enum {
    UNKNOWN = 0;
    HAS_MAILBOX = 2;
    NO_MAILBOX = 3;
  }

  Enum value = 1;
}

// Generic message for debug execution results.
// Used for specific targeting criteria
message ExecutionResult {
  // if current criteria is applicable/eligible/valid
  bool success = 1;
  // if set - it's JSON with either string, date utc string, boolean, array or object
  // depends on specific filter/criteria the result is calculated
  google.protobuf.StringValue current_value = 2;
}

message UserStatusCriteria {
  enum Enum {
    UNKNOWN = 0;
    NEW = 1;
  }

  Enum value = 1;
}

message DomainLengthCriteria {
  // WARNING: bad naming for JS context => hidden bugs
  // For example lodash considers objects with `length` property ArrayLike
  int32 length = 1;
  bool shorter_or_equal = 2;
}

message FreeSiteCriteria {
  enum Enum {
    UNKNOWN = 0;
    HAS_FREE = 1;
    NO_FREE = 2;
  }

  Enum value = 1;
}

// Filter for list of brands
// (i.e. if given offer must be shown to user for "only [wix]",
// of "only [wix, editorx]", or "except [editorx]" etc.)
message BrandsCriteria {
  enum Brand {
    UNKNOWN = 0;
    WIX = 1;
    EDITORX = 2;
    DAYFUL = 3;
    STUDIO = 4;
  }

  repeated Brand values = 1;
  bool included = 2;
}

message SiteTypeCriteria {
  enum SiteType {
    UNKNOWN = 0;
    REGULAR = 1;
    HEADLESS = 2;
  }

  repeated SiteType values = 1 [(.wix.api.minSize) = 1, (.wix.api.maxSize) = 10000];
  bool included = 2;
}

message CustomParamCriteria {
  enum CustomParamOperator {
    UNKNOWN = 0;
    EQUALS = 1;
    NOT_EQUALS = 2;
    CONTAINS_ALL = 3;
    NOT_CONTAINS_ALL = 4;
    CONTAINS_ANY = 5;
    NOT_CONTAINS_ANY = 6;
    EXISTS = 7;
    NOT_EXISTS = 8;
  }
  CustomParamOperator operator = 1;
  google.protobuf.StringValue key = 2;
  repeated google.protobuf.StringValue values = 3;
  CriteriaMetaData criteriaMetaData = 4;
}

message ExperimentCriteria {
  google.protobuf.StringValue spec = 1;
  google.protobuf.StringValue value = 2;
}

message PremiumAccountCriteria {
  enum Enum {
    UNKNOWN = 0;
    IS_PREMIUM = 1;
    IS_NOT_PREMIUM = 2;
  }

  Enum value = 1;
}

message ExternalCriteria {
  message ConditionType {
    enum Enum {
      UNKNOWN = 0;
      EQUAL = 1;
      GREATER_THAN = 2;
      SMALLER_THAN = 3;
    }
  }

  google.protobuf.StringValue artifact_name = 1;
  ConditionType.Enum condition_type = 2;
  reserved 3;
  google.protobuf.Value expected_value = 4; // This should be validated against ResponseType and ConditionType
  google.protobuf.Struct additional_params = 5;
}

message EligibleForSaleCriteria {
  enum Enum {
    UNKNOWN = 0;
    NONE = 1;
    SEASONAL = 2;
    PERSONAL = 3;
    CUSTOM = 4;
  }

  Enum value = 1;
  google.protobuf.StringValue customSale = 2;
  string productTypeId = 3 [(wix.api.format) = GUID];
}
