// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.cloud.contentwarehouse.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/iam/v1/policy.proto";

option csharp_namespace = "Google.Cloud.ContentWarehouse.V1";
option go_package = "cloud.google.com/go/contentwarehouse/apiv1/contentwarehousepb;contentwarehousepb";
option java_multiple_files = true;
option java_outer_classname = "RuleEngineProto";
option java_package = "com.google.cloud.contentwarehouse.v1";
option php_namespace = "Google\\Cloud\\ContentWarehouse\\V1";
option ruby_package = "Google::Cloud::ContentWarehouse::V1";

// Represents a set of rules from a single customer.
message RuleSet {
  option (google.api.resource) = {
    type: "contentwarehouse.googleapis.com/RuleSet"
    pattern: "projects/{project}/locations/{location}/ruleSets/{rule_set}"
  };

  // The resource name of the rule set. Managed internally.
  // Format:
  // projects/{project_number}/locations/{location}/ruleSet/{rule_set_id}.
  //
  // The name is ignored when creating a rule set.
  string name = 6;

  // Short description of the rule-set.
  string description = 1;

  // Source of the rules i.e., customer name.
  string source = 2;

  // List of rules given by the customer.
  repeated Rule rules = 3;
}

// Represents the rule for a content warehouse trigger.
message Rule {
  // The trigger types for actions.
  enum TriggerType {
    // Trigger for unknown action.
    UNKNOWN = 0;

    // Trigger for create document action.
    ON_CREATE = 1;

    // Trigger for update document action.
    ON_UPDATE = 4;

    // Trigger for create link action.
    ON_CREATE_LINK = 7;

    // Trigger for delete link action.
    ON_DELETE_LINK = 8;
  }

  // Short description of the rule and its context.
  string description = 1;

  // ID of the rule. It has to be unique across all the examples.
  // This is managed internally.
  string rule_id = 2;

  // Identifies the trigger type for running the policy.
  TriggerType trigger_type = 3;

  // Represents the conditional expression to be evaluated.
  // Expression should evaluate to a boolean result.
  // When the condition is true actions are executed.
  // Example: user_role = "hsbc_role_1" AND doc.salary > 20000
  string condition = 4;

  // List of actions that are executed when the rule is satisfied.
  repeated Action actions = 5;
}

// Represents the action triggered by Rule Engine when the rule is true.
message Action {
  // ID of the action. Managed internally.
  string action_id = 1;

  oneof action {
    // Action triggering access control operations.
    AccessControlAction access_control = 2;

    // Action triggering data validation operations.
    DataValidationAction data_validation = 3;

    // Action triggering data update operations.
    DataUpdateAction data_update = 4;

    // Action triggering create document link operation.
    AddToFolderAction add_to_folder = 5;

    // Action publish to Pub/Sub operation.
    PublishAction publish_to_pub_sub = 6;

    // Action removing a document from a folder.
    RemoveFromFolderAction remove_from_folder_action = 9;

    // Action deleting the document.
    DeleteDocumentAction delete_document_action = 10;
  }
}

// Represents the action responsible for access control list management
// operations.
message AccessControlAction {
  // Type of ACL modification operation.
  enum OperationType {
    // The unknown operation type.
    UNKNOWN = 0;

    // Adds newly given policy bindings in the existing bindings list.
    ADD_POLICY_BINDING = 1;

    // Removes newly given policy bindings from the existing bindings list.
    REMOVE_POLICY_BINDING = 2;

    // Replaces existing policy bindings with the given policy binding list
    REPLACE_POLICY_BINDING = 3;
  }

  // Identifies the type of operation.
  OperationType operation_type = 1;

  // Represents the new policy from which bindings are added, removed or
  // replaced based on the type of the operation. the policy is limited to a few
  // 10s of KB.
  google.iam.v1.Policy policy = 2;
}

// Represents the action responsible for data validation operations.
message DataValidationAction {
  // Map of (K, V) -> (field, string condition to be evaluated on the field)
  // E.g., ("age", "age > 18  && age < 60") entry triggers validation of field
  // age with the given condition. Map entries will be ANDed during validation.
  map<string, string> conditions = 1;
}

// Represents the action responsible for properties update operations.
message DataUpdateAction {
  // Map of (K, V) -> (valid name of the field, new value of the field)
  // E.g., ("age", "60") entry triggers update of field age with a value of 60.
  // If the field is not present then new entry is added.
  // During update action execution, value strings will be casted to
  // appropriate types.
  map<string, string> entries = 1;
}

// Represents the action responsible for adding document under a folder.
message AddToFolderAction {
  // Names of the folder under which new document is to be added.
  // Format:
  // projects/{project_number}/locations/{location}/documents/{document_id}.
  repeated string folders = 1 [(google.api.resource_reference) = {
    type: "contentwarehouse.googleapis.com/Document"
  }];
}

// Represents the action responsible for remove a document from a specific
// folder.
message RemoveFromFolderAction {
  // Condition of the action to be executed.
  string condition = 1;

  // Name of the folder under which new document is to be added.
  // Format:
  // projects/{project_number}/locations/{location}/documents/{document_id}.
  string folder = 2 [(google.api.resource_reference) = {
    type: "contentwarehouse.googleapis.com/Document"
  }];
}

// Represents the action responsible for publishing messages to a Pub/Sub topic.
message PublishAction {
  // The topic id in the Pub/Sub service for which messages will be published
  // to.
  string topic_id = 1;

  // Messages to be published.
  repeated string messages = 2;
}

// Represents the action responsible for deleting the document.
message DeleteDocumentAction {
  // Boolean field to select between hard vs soft delete options.
  // Set 'true' for 'hard delete' and 'false' for 'soft delete'.
  bool enable_hard_delete = 1;
}

// Records the output of Rule Engine including rule evaluation and actions
// result.
message RuleEngineOutput {
  // Name of the document against which the rules and actions were evaluated.
  string document_name = 3;

  // Output from Rule Evaluator containing matched, unmatched and invalid rules.
  RuleEvaluatorOutput rule_evaluator_output = 1;

  // Output from Action Executor containing rule and corresponding actions
  // execution result.
  ActionExecutorOutput action_executor_output = 2;
}

// Represents the output of the Rule Evaluator.
message RuleEvaluatorOutput {
  // List of rules fetched from database for the given request trigger type.
  repeated Rule triggered_rules = 1;

  // A subset of triggered rules that are evaluated true for a given request.
  repeated Rule matched_rules = 2;

  // A subset of triggered rules that failed the validation check(s) after
  // parsing.
  repeated InvalidRule invalid_rules = 3;
}

// A triggered rule that failed the validation check(s) after parsing.
message InvalidRule {
  // Triggered rule.
  Rule rule = 1;

  // Validation error on a parsed expression.
  string error = 2;
}

// Represents the output of the Action Executor.
message ActionExecutorOutput {
  // List of rule and corresponding actions result.
  repeated RuleActionsPair rule_actions_pairs = 1;
}

// Represents a rule and outputs of associated actions.
message RuleActionsPair {
  // Represents the rule.
  Rule rule = 1;

  // Outputs of executing the actions associated with the above rule.
  repeated ActionOutput action_outputs = 2;
}

// Represents the result of executing an action.
message ActionOutput {
  // Represents execution state of the action.
  enum State {
    // The unknown state.
    UNKNOWN = 0;

    // State indicating action executed successfully.
    ACTION_SUCCEEDED = 1;

    // State indicating action failed.
    ACTION_FAILED = 2;

    // State indicating action timed out.
    ACTION_TIMED_OUT = 3;

    // State indicating action is pending.
    ACTION_PENDING = 4;
  }

  // ID of the action.
  string action_id = 1;

  // State of an action.
  State action_state = 2;

  // Action execution output message.
  string output_message = 3;
}
