// Copyright 2024 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.workflows.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";

option go_package = "cloud.google.com/go/workflows/apiv1/workflowspb;workflowspb";
option java_multiple_files = true;
option java_outer_classname = "WorkflowsProto";
option java_package = "com.google.cloud.workflows.v1";
option (google.api.resource_definition) = {
  type: "cloudkms.googleapis.com/CryptoKey"
  pattern: "projects/{project}/locations/{location}/keyRings/{keyRing}/cryptoKeys/{cryptoKey}"
};

// Workflows is used to deploy and execute workflow programs.
// Workflows makes sure the program executes reliably, despite hardware and
// networking interruptions.
service Workflows {
  option (google.api.default_host) = "workflows.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Lists workflows in a given project and location.
  // The default order is not specified.
  rpc ListWorkflows(ListWorkflowsRequest) returns (ListWorkflowsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/workflows"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets details of a single workflow.
  rpc GetWorkflow(GetWorkflowRequest) returns (Workflow) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/workflows/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a new workflow. If a workflow with the specified name already
  // exists in the specified project and location, the long running operation
  // returns a [ALREADY_EXISTS][google.rpc.Code.ALREADY_EXISTS] error.
  rpc CreateWorkflow(CreateWorkflowRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/workflows"
      body: "workflow"
    };
    option (google.api.method_signature) = "parent,workflow,workflow_id";
    option (google.longrunning.operation_info) = {
      response_type: "Workflow"
      metadata_type: "OperationMetadata"
    };
  }

  // Deletes a workflow with the specified name.
  // This method also cancels and deletes all running executions of the
  // workflow.
  rpc DeleteWorkflow(DeleteWorkflowRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/workflows/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "OperationMetadata"
    };
  }

  // Updates an existing workflow.
  // Running this method has no impact on already running executions of the
  // workflow. A new revision of the workflow might be created as a result of a
  // successful update operation. In that case, the new revision is used
  // in new workflow executions.
  rpc UpdateWorkflow(UpdateWorkflowRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      patch: "/v1/{workflow.name=projects/*/locations/*/workflows/*}"
      body: "workflow"
    };
    option (google.api.method_signature) = "workflow,update_mask";
    option (google.longrunning.operation_info) = {
      response_type: "Workflow"
      metadata_type: "OperationMetadata"
    };
  }
}

// Workflow program to be executed by Workflows.
message Workflow {
  option (google.api.resource) = {
    type: "workflows.googleapis.com/Workflow"
    pattern: "projects/{project}/locations/{location}/workflows/{workflow}"
  };

  // Describes the current state of workflow deployment.
  enum State {
    // Invalid state.
    STATE_UNSPECIFIED = 0;

    // The workflow has been deployed successfully and is serving.
    ACTIVE = 1;

    // Workflow data is unavailable. See the `state_error` field.
    UNAVAILABLE = 2;
  }

  // Describes an error related to the current state of the workflow.
  message StateError {
    // Describes the possibled types of a state error.
    enum Type {
      // No type specified.
      TYPE_UNSPECIFIED = 0;

      // Caused by an issue with KMS.
      KMS_ERROR = 1;
    }

    // Provides specifics about the error.
    string details = 1;

    // The type of this state error.
    Type type = 2;
  }

  // Describes the level of platform logging to apply to calls and call
  // responses during workflow executions.
  enum CallLogLevel {
    // No call logging level specified.
    CALL_LOG_LEVEL_UNSPECIFIED = 0;

    // Log all call steps within workflows, all call returns, and all exceptions
    // raised.
    LOG_ALL_CALLS = 1;

    // Log only exceptions that are raised from call steps within workflows.
    LOG_ERRORS_ONLY = 2;

    // Explicitly log nothing.
    LOG_NONE = 3;
  }

  // The resource name of the workflow.
  // Format: projects/{project}/locations/{location}/workflows/{workflow}
  string name = 1;

  // Description of the workflow provided by the user.
  // Must be at most 1000 unicode characters long.
  string description = 2;

  // Output only. State of the workflow deployment.
  State state = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The revision of the workflow.
  // A new revision of a workflow is created as a result of updating the
  // following properties of a workflow:
  //
  // - [Service account][google.cloud.workflows.v1.Workflow.service_account]
  // - [Workflow code to be
  // executed][google.cloud.workflows.v1.Workflow.source_contents]
  //
  // The format is "000001-a4d", where the first six characters define
  // the zero-padded revision ordinal number. They are followed by a hyphen and
  // three hexadecimal random characters.
  string revision_id = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp for when the workflow was created.
  google.protobuf.Timestamp create_time = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp for when the workflow was last updated.
  google.protobuf.Timestamp update_time = 6
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp for the latest revision of the workflow's
  // creation.
  google.protobuf.Timestamp revision_create_time = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Labels associated with this workflow.
  // Labels can contain at most 64 entries. Keys and values can be no longer
  // than 63 characters and can only contain lowercase letters, numeric
  // characters, underscores, and dashes. Label keys must start with a letter.
  // International characters are allowed.
  map<string, string> labels = 8;

  // The service account associated with the latest workflow version.
  // This service account represents the identity of the workflow and determines
  // what permissions the workflow has.
  // Format: projects/{project}/serviceAccounts/{account} or {account}
  //
  // Using `-` as a wildcard for the `{project}` or not providing one at all
  // will infer the project from the account. The `{account}` value can be the
  // `email` address or the `unique_id` of the service account.
  //
  // If not provided, workflow will use the project's default service account.
  // Modifying this field for an existing workflow results in a new workflow
  // revision.
  string service_account = 9;

  // Required. Location of the workflow source code.
  // Modifying this field for an existing workflow results in a new workflow
  // revision.
  oneof source_code {
    // Workflow code to be executed. The size limit is 128KB.
    string source_contents = 10;
  }

  // Optional. The resource name of a KMS crypto key used to encrypt or decrypt
  // the data associated with the workflow.
  //
  // Format:
  // projects/{project}/locations/{location}/keyRings/{keyRing}/cryptoKeys/{cryptoKey}
  //
  // Using `-` as a wildcard for the `{project}` or not providing one at all
  // will infer the project from the account.
  //
  // If not provided, data associated with the workflow will not be
  // CMEK-encrypted.
  string crypto_key_name = 11 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      type: "cloudkms.googleapis.com/CryptoKey"
    }
  ];

  // Output only. Error regarding the state of the workflow. For example, this
  // field will have error details if the execution data is unavailable due to
  // revoked KMS key permissions.
  StateError state_error = 12 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Describes the level of platform logging to apply to calls and
  // call responses during executions of this workflow. If both the workflow and
  // the execution specify a logging level, the execution level takes
  // precedence.
  CallLogLevel call_log_level = 13 [(google.api.field_behavior) = OPTIONAL];

  // Optional. User-defined environment variables associated with this workflow
  // revision. This map has a maximum length of 20. Each string can take up to
  // 40KiB. Keys cannot be empty strings and cannot start with “GOOGLE” or
  // “WORKFLOWS".
  map<string, string> user_env_vars = 14
      [(google.api.field_behavior) = OPTIONAL];
}

// Request for the
// [ListWorkflows][google.cloud.workflows.v1.Workflows.ListWorkflows]
// method.
message ListWorkflowsRequest {
  // Required. Project and location from which the workflows should be listed.
  // Format: projects/{project}/locations/{location}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Maximum number of workflows to return per call. The service might return
  // fewer than this value even if not at the end of the collection. If a value
  // is not specified, a default value of 500 is used. The maximum permitted
  // value is 1000 and values greater than 1000 are coerced down to 1000.
  int32 page_size = 2;

  // A page token, received from a previous `ListWorkflows` call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to `ListWorkflows` must
  // match the call that provided the page token.
  string page_token = 3;

  // Filter to restrict results to specific workflows.
  string filter = 4;

  // Comma-separated list of fields that specify the order of the results.
  // Default sorting order for a field is ascending. To specify descending order
  // for a field, append a "desc" suffix.
  // If not specified, the results are returned in an unspecified order.
  string order_by = 5;
}

// Response for the
// [ListWorkflows][google.cloud.workflows.v1.Workflows.ListWorkflows]
// method.
message ListWorkflowsResponse {
  // The workflows that match the request.
  repeated Workflow workflows = 1;

  // A token, which can be sent as `page_token` to retrieve the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 2;

  // Unreachable resources.
  repeated string unreachable = 3;
}

// Request for the
// [GetWorkflow][google.cloud.workflows.v1.Workflows.GetWorkflow] method.
message GetWorkflowRequest {
  // Required. Name of the workflow for which information should be retrieved.
  // Format: projects/{project}/locations/{location}/workflows/{workflow}
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "workflows.googleapis.com/Workflow"
    }
  ];

  // Optional. The revision of the workflow to retrieve. If the revision_id is
  // empty, the latest revision is retrieved.
  // The format is "000001-a4d", where the first six characters define
  // the zero-padded decimal revision number. They are followed by a hyphen and
  // three hexadecimal characters.
  string revision_id = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request for the
// [CreateWorkflow][google.cloud.workflows.v1.Workflows.CreateWorkflow]
// method.
message CreateWorkflowRequest {
  // Required. Project and location in which the workflow should be created.
  // Format:  projects/{project}/locations/{location}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "locations.googleapis.com/Location"
    }
  ];

  // Required. Workflow to be created.
  Workflow workflow = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The ID of the workflow to be created. It has to fulfill the
  // following requirements:
  //
  // * Must contain only letters, numbers, underscores and hyphens.
  // * Must start with a letter.
  // * Must be between 1-64 characters.
  // * Must end with a number or a letter.
  // * Must be unique within the customer project and location.
  string workflow_id = 3 [(google.api.field_behavior) = REQUIRED];
}

// Request for the
// [DeleteWorkflow][google.cloud.workflows.v1.Workflows.DeleteWorkflow]
// method.
message DeleteWorkflowRequest {
  // Required. Name of the workflow to be deleted.
  // Format: projects/{project}/locations/{location}/workflows/{workflow}
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "workflows.googleapis.com/Workflow"
    }
  ];
}

// Request for the
// [UpdateWorkflow][google.cloud.workflows.v1.Workflows.UpdateWorkflow]
// method.
message UpdateWorkflowRequest {
  // Required. Workflow to be updated.
  Workflow workflow = 1 [(google.api.field_behavior) = REQUIRED];

  // List of fields to be updated. If not present, the entire workflow
  // will be updated.
  google.protobuf.FieldMask update_mask = 2;
}

// Represents the metadata of the long-running operation.
message OperationMetadata {
  // The time the operation was created.
  google.protobuf.Timestamp create_time = 1;

  // The time the operation finished running.
  google.protobuf.Timestamp end_time = 2;

  // Server-defined resource path for the target of the operation.
  string target = 3;

  // Name of the verb executed by the operation.
  string verb = 4;

  // API version used to start the operation.
  string api_version = 5;
}
