syntax = "proto3";

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

package com.wixpress.appservice.api.upstream.com.wixpress.automations.service;

// Automation Component data that is stored in dev center
message ApplicationAutomationComponent {
  // A rule that contains a trigger & some actions
  Rule rule = 1;

  // Automation name
  google.protobuf.StringValue name = 2 [(.wix.api.maxLength) = 500];

  // Automation description
  google.protobuf.StringValue description = 3 [(.wix.api.maxLength) = 2000];

  // Automation metadata
  AutomationMetadata metadata = 4;

  // Automation status
  Status status = 5;

  // Optional origin that indicates the source of the automation
  OriginInfo origin = 6;

  // Automation id - points to a V3 Builder automation id
  google.protobuf.StringValue automation_id = 7 [(.wix.api.format) = GUID];

  // trigger app id - used for reading easily for cache - v3
  google.protobuf.StringValue trigger_app_id = 8 [(.wix.api.format) = GUID];

  // trigger key - used for reading easily for cache - v3
  google.protobuf.StringValue trigger_key = 9 [(.wix.api.minLength) = 1, (.wix.api.maxLength) = 100];

  enum Status {
    ACTIVE = 0;
    INACTIVE = 1;
  }

  message OriginInfo {
    // The id of the original automation used to create the preinstalled automation (v3/Builder only)
    string site_automation_id = 1 [(.wix.api.format) = GUID];

    // The site which the automation was originally created in (v3/Builder only)
    string meta_site_id = 2 [(.wix.api.format) = GUID];

  }
}

message AutomationMetadata {
  // Is this Automation hidden on a site?
  bool hidden = 1;

  // Can this Automation be deactivated on a site?
  bool always_active = 2;

  // Is this Automation's scheduling modification is disabled on a site?
  bool scheduling_modification_disabled = 3;

  // Is the removal of this Automation's actions disabled?
  bool action_removal_disabled = 4;

  // Is conditions editing for this Automation allowed on a site?
  bool action_conditions_editing_disabled = 5;

  // Domain
  Domain domain = 6 [(.wix.api.immutable) = true, (.wix.api.field_exposure) = INTERNAL, (.wix.api.field_maturity) = NOT_IMPLEMENTED];

  enum Domain {
    // User domain (default)
    USER = 0;
    // Wix domain
    WIX = 1;
  }
}

message Rule {
  option (.wix.api.decomposite_of) = "com.wixpress.automations.service.Rule";
  // an event triggered by visitors on a site, or by a site manager (owner & team).
  Trigger trigger = 1;
  // the actions responding to the trigger happening
  repeated Action actions = 2 [(.wix.api.minSize) = 0, (.wix.api.maxSize) = 100];
}

message Trigger {
  option (.wix.api.decomposite_of) = "com.wixpress.automations.service.Trigger";
  // the id of the app defining the trigger
  string app_id = 1 [(.wix.api.format) = GUID];
  // Identifier for this trigger - human readable action key
  string trigger_key = 2 [(.wix.api.maxLength) = 100];
  // optional list of filters on schema fields
  repeated Filter filters = 3 [(.wix.api.maxSize) = 5];

  // optional - allows to define a trigger whose following actions will be executed only if the same event for the same resource has not in the last X seconds.
  // for example, if the trigger is "session booked", the resource is a contact and the timeframe is 3600 seconds (contact hasn't booked another session in the last hour),
  // then the actions will be executed only if the same event (session booked for that contact) has not happened in the last hour.
  // resource id is sent in runtime via the externalEntityId parameter, ReportEvent method.
  Debounce debounce = 4;

  message Debounce {
    // Amount of time in seconds to wait for any additional events to occur before triggering the actions.
    // If no additional events occur within the specified time, the actions will be triggered.
    // If additional events occur within the specified time, the timer will be reset.
    int32 time_frame_in_seconds = 1 [(.wix.api.min) = 1];

    // The field key in the event payload, which indicates the identifier of the entity/event to debounce on
    // For example: if the trigger is "user logged in", the resource is a contact and the resource key is "contactId",
    // Another example: if the trigger is "visitor logged in", the resource is a visitor and the resource key is "visitorId".
    string field_key = 2 [(.wix.api.minLength) = 0, (.wix.api.maxLength) = 100];
  }

  message Filter {
    // the filter identifier
    google.protobuf.StringValue id = 3 [(.wix.api.format) = GUID];
    // the field key from the schema, for example "formId"
    string field_key  = 1 [(.wix.api.minLength) = 1, (.wix.api.maxLength) = 50];
    // filter expression that evaluates to a boolean, for example - {{ contains(["guid1","guid2"];formId) }}
    string filter_expression = 2;
  }
}

message Action {
  option (.wix.api.decomposite_of) = "com.wixpress.automations.service.Action";
  // the id of the action for delayed events
  google.protobuf.StringValue id = 1 [(.wix.api.format) = GUID, (.wix.api.readOnly) = true];

  // the id of the app defining the action
  string app_id = 2 [(.wix.api.format) = GUID];

  // Identifier for this action - human readable action key - unique per app def id
  string action_key = 3 [(.wix.api.maxLength) = 80];

  // input mapping expression for the action inputs
  // for example:
  // `{  "subject": "Thanks for reaching out!"
  //    "message": "Hi {{contact.name.first}}, thanks for contacting our business"
  //  }`
  //  where the value for "contact.name.first" comes from the trigger's payload
  string action_config = 4 [(.wix.api.minLength) = 0, (.wix.api.maxLength) = 5000];

  // output mapping expression for the action output
  // for example in get-contact action:
  // `{ "author": "{{$}}" }`
  // This will map the entire entity of contact under `author` namespace
  google.protobuf.StringValue output_action_config = 5 [(.wix.api.minLength) = 0, (.wix.api.maxLength) = 3000];

  // Optional delay configuration for the action
  Delay delay = 6;

  // allows you define an activation policy - like number of activations in a time frame, or limit by some identifier, like contact (e.g. send email to user only at first login)
  RateLimit rate_limit = 7;

  // allows the user to define a condition for the action to be executed, if the condition fails the action (and following actions) will not be executed
  Condition condition = 8 [(.wix.api.field_deprecated) = {
    replaced_by: "conditions"
    target_removal_date: "2023-08-01"
  }];

  Conditions conditions = 9;
  
  // allows the user to define a namespace for the action output
  google.protobuf.StringValue namespace = 10 [(.wix.api.minLength) = 1, (.wix.api.maxLength) = 100];

  message Conditions {
    // condition evaluates to `true` if either of the blocks evaluate to `true` (aka OR between all)
    repeated ConditionBlock condition_blocks = 1 [(.wix.api.minSize) = 1, (.wix.api.maxSize) = 10];

    message ConditionBlock {
      BlockType type = 1;
      repeated string line_expressions = 2 [(.wix.api.minSize) = 1, (.wix.api.maxSize) = 20];
    }

    enum BlockType {
      UNKNOWN = 0;
      OR = 1;
      AND = 2;
    }
  }

  message Delay {
    oneof type {
      // A delay which is calculated based on the immediate time when the action is triggered.
      Offset for    = 1;
      // A delay which is calculated based on a date field in the trigger payload. May also be used together with an Offset delay.
      Until until   = 2;
    }

    message Offset {
      oneof value {
        // A delay in seconds
        int32 seconds     = 1;
        // The key of the field in the trigger payload which contains a delay, in seconds.
        string delay_field_key = 2;
      }
    }

    // calculated as date + delay
    message Until {
      // The key of the field in the trigger payload which contains the date to delay until
      string date_field_key = 1;

      // Optional: a delay to add together with the date described in the payload
      Offset offset         = 2;
    }
  }

  message RateLimit {
    // time frame in minutes
    google.protobuf.Int32Value time_frame = 1 [(.wix.api.min) = 1];

    // number of activations allowed in the given time frame
    int32 activations = 2 [(.wix.api.min) = 1];

    // limit the activation by an entity, for example activate once per contact. example: {{contact.id}}
    google.protobuf.StringValue unique_identifier_expression = 3 [(.wix.api.minLength) = 1, (.wix.api.maxLength) = 300];
  }

  message Condition {
    // entity object is deprecated due to the new approach to conditions
    // the condition expression, for example - {{and(gt(price;10);lt(price;100))}}
    string condition_expression = 1 [(.wix.api.minLength) = 1, (.wix.api.maxLength) = 2000];
  }
}
