// The MIT License
//
// Copyright (c) 2020 Temporal Technologies Inc.  All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

syntax = "proto3";

package temporal.api.command.v1;

option go_package = "go.temporal.io/api/command/v1;command";
option java_package = "io.temporal.api.command.v1";
option java_multiple_files = true;
option java_outer_classname = "MessageProto";
option ruby_package = "Temporalio::Api::Command::V1";
option csharp_namespace = "Temporalio.Api.Command.V1";

import "google/protobuf/duration.proto";

import "temporal/api/enums/v1/workflow.proto";
import "temporal/api/enums/v1/command_type.proto";
import "temporal/api/common/v1/message.proto";
import "temporal/api/failure/v1/message.proto";
import "temporal/api/taskqueue/v1/message.proto";
import "temporal/api/sdk/v1/user_metadata.proto";

message ScheduleActivityTaskCommandAttributes {
    string activity_id = 1;
    temporal.api.common.v1.ActivityType activity_type = 2;
    // This used to be a `namespace` field which allowed to schedule activity in another namespace.
    reserved 3;
    temporal.api.taskqueue.v1.TaskQueue task_queue = 4;
    temporal.api.common.v1.Header header = 5;
    temporal.api.common.v1.Payloads input = 6;
    // Indicates how long the caller is willing to wait for activity completion. The "schedule" time
    // is when the activity is initially scheduled, not when the most recent retry is scheduled.
    // Limits how long retries will be attempted. Either this or `start_to_close_timeout` must be
    // specified. When not specified, defaults to the workflow execution timeout.
    //
    // (-- api-linter: core::0140::prepositions=disabled
    //     aip.dev/not-precedent: "to" is used to indicate interval. --)
    google.protobuf.Duration schedule_to_close_timeout = 7;
    // Limits the time an activity task can stay in a task queue before a worker picks it up. The
    // "schedule" time is when the most recent retry is scheduled. This timeout should usually not
    // be set: it's useful in specific scenarios like worker-specific task queues. This timeout is
    // always non retryable, as all a retry would achieve is to put it back into the same queue.
    // Defaults to `schedule_to_close_timeout` or workflow execution timeout if that is not
    // specified. More info:
    // https://docs.temporal.io/docs/content/what-is-a-schedule-to-start-timeout/
    //
    // (-- api-linter: core::0140::prepositions=disabled
    //     aip.dev/not-precedent: "to" is used to indicate interval. --)
    google.protobuf.Duration schedule_to_start_timeout = 8;
    // Maximum time an activity is allowed to execute after being picked up by a worker. This
    // timeout is always retryable. Either this or `schedule_to_close_timeout` must be specified.
    //
    // (-- api-linter: core::0140::prepositions=disabled
    //     aip.dev/not-precedent: "to" is used to indicate interval. --)
    google.protobuf.Duration start_to_close_timeout = 9;
    // Maximum permitted time between successful worker heartbeats.
    google.protobuf.Duration heartbeat_timeout = 10;
    // Activities are provided by a default retry policy which is controlled through the service's
    // dynamic configuration. Retries will be attempted until `schedule_to_close_timeout` has
    // elapsed. To disable retries set retry_policy.maximum_attempts to 1.
    temporal.api.common.v1.RetryPolicy retry_policy = 11;
    // Request to start the activity directly bypassing matching service and worker polling
    // The slot for executing the activity should be reserved when setting this field to true.
    bool request_eager_execution = 12;
    // If this is set, the activity would be assigned to the Build ID of the workflow. Otherwise,
    // Assignment rules of the activity's Task Queue will be used to determine the Build ID.
    bool use_workflow_build_id = 13;
}

message RequestCancelActivityTaskCommandAttributes {
    // The `ACTIVITY_TASK_SCHEDULED` event id for the activity being cancelled.
    int64 scheduled_event_id = 1;
}

message StartTimerCommandAttributes {
    // An id for the timer, currently live timers must have different ids. Typically autogenerated
    // by the SDK.
    string timer_id = 1;
    // How long until the timer fires, producing a `TIMER_FIRED` event.
    //
    // (-- api-linter: core::0140::prepositions=disabled
    //     aip.dev/not-precedent: "to" is used to indicate interval. --)
    google.protobuf.Duration start_to_fire_timeout = 2;
}

message CompleteWorkflowExecutionCommandAttributes {
    temporal.api.common.v1.Payloads result = 1;
}

message FailWorkflowExecutionCommandAttributes {
    temporal.api.failure.v1.Failure failure = 1;
}

message CancelTimerCommandAttributes {
    // The same timer id from the start timer command
    string timer_id = 1;
}

message CancelWorkflowExecutionCommandAttributes {
    temporal.api.common.v1.Payloads details = 1;
}

message RequestCancelExternalWorkflowExecutionCommandAttributes {
    string namespace = 1;
    string workflow_id = 2;
    string run_id = 3;
    // Deprecated.
    string control = 4;
    // Set this to true if the workflow being cancelled is a child of the workflow originating this
    // command. The request will be rejected if it is set to true and the target workflow is *not*
    // a child of the requesting workflow.
    bool child_workflow_only = 5;
    // Reason for requesting the cancellation
    string reason = 6;
}

message SignalExternalWorkflowExecutionCommandAttributes {
    string namespace = 1;
    temporal.api.common.v1.WorkflowExecution execution = 2;
    // The workflow author-defined name of the signal to send to the workflow.
    string signal_name = 3;
    // Serialized value(s) to provide with the signal.
    temporal.api.common.v1.Payloads input = 4;
    // Deprecated
    string control = 5;
    // Set this to true if the workflow being cancelled is a child of the workflow originating this
    // command. The request will be rejected if it is set to true and the target workflow is *not*
    // a child of the requesting workflow.
    bool child_workflow_only = 6;
    // Headers that are passed by the workflow that is sending a signal to the external 
    // workflow that is receiving this signal.
    temporal.api.common.v1.Header header = 7;
}

message UpsertWorkflowSearchAttributesCommandAttributes {
    temporal.api.common.v1.SearchAttributes search_attributes = 1;
}

message ModifyWorkflowPropertiesCommandAttributes {
    // If set, update the workflow memo with the provided values. The values will be merged with
    // the existing memo. If the user wants to delete values, a default/empty Payload should be
    // used as the value for the key being deleted.
    temporal.api.common.v1.Memo upserted_memo = 1;
}

message RecordMarkerCommandAttributes {
    string marker_name = 1;
    map<string, temporal.api.common.v1.Payloads> details = 2;
    temporal.api.common.v1.Header header = 3;
    temporal.api.failure.v1.Failure failure = 4;
}

message ContinueAsNewWorkflowExecutionCommandAttributes {
    temporal.api.common.v1.WorkflowType workflow_type = 1;
    temporal.api.taskqueue.v1.TaskQueue task_queue = 2;
    temporal.api.common.v1.Payloads input = 3;

    // Timeout of a single workflow run.
    google.protobuf.Duration workflow_run_timeout = 4;
    // Timeout of a single workflow task.
    google.protobuf.Duration workflow_task_timeout = 5;
    // How long the workflow start will be delayed - not really a "backoff" in the traditional sense.
    google.protobuf.Duration backoff_start_interval = 6;
    temporal.api.common.v1.RetryPolicy retry_policy = 7;
    // Should be removed
    temporal.api.enums.v1.ContinueAsNewInitiator initiator = 8;
    // Should be removed
    temporal.api.failure.v1.Failure failure = 9;
    // Should be removed
    temporal.api.common.v1.Payloads last_completion_result = 10;
    // Should be removed. Not necessarily unused but unclear and not exposed by SDKs.
    string cron_schedule = 11;
    temporal.api.common.v1.Header header = 12;
    temporal.api.common.v1.Memo memo = 13;
    temporal.api.common.v1.SearchAttributes search_attributes = 14;
    // If this is set, the new execution inherits the Build ID of the current execution. Otherwise,
    // the assignment rules will be used to independently assign a Build ID to the new execution.
    bool inherit_build_id = 15;

    // `workflow_execution_timeout` is omitted as it shouldn't be overridden from within a workflow.
}

message StartChildWorkflowExecutionCommandAttributes {
    string namespace = 1;
    string workflow_id = 2;
    temporal.api.common.v1.WorkflowType workflow_type = 3;
    temporal.api.taskqueue.v1.TaskQueue task_queue = 4;
    temporal.api.common.v1.Payloads input = 5;
    // Total workflow execution timeout including retries and continue as new.
    google.protobuf.Duration workflow_execution_timeout = 6;
    // Timeout of a single workflow run.
    google.protobuf.Duration workflow_run_timeout = 7;
    // Timeout of a single workflow task.
    google.protobuf.Duration workflow_task_timeout = 8;
    // Default: PARENT_CLOSE_POLICY_TERMINATE.
    temporal.api.enums.v1.ParentClosePolicy parent_close_policy = 9;
    string control = 10;
    // Default: WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE.
    temporal.api.enums.v1.WorkflowIdReusePolicy workflow_id_reuse_policy = 11;
    temporal.api.common.v1.RetryPolicy retry_policy = 12;
    // Establish a cron schedule for the child workflow.
    string cron_schedule = 13;
    temporal.api.common.v1.Header header = 14;
    temporal.api.common.v1.Memo memo = 15;
    temporal.api.common.v1.SearchAttributes search_attributes = 16;
    // If this is set, the child workflow inherits the Build ID of the parent. Otherwise, the assignment
    // rules of the child's Task Queue will be used to independently assign a Build ID to it.
    bool inherit_build_id = 17;
}

message ProtocolMessageCommandAttributes {
    // The message ID of the message to which this command is a pointer.
    string message_id = 1;
}

message ScheduleNexusOperationCommandAttributes {
    // Endpoint name, must exist in the endpoint registry or this command will fail.
    string endpoint = 1;
    // Service name.
    string service = 2;
    // Operation name.
    string operation = 3;
    // Input for the operation. The server converts this into Nexus request content and the appropriate content headers
    // internally when sending the StartOperation request. On the handler side, if it is also backed by Temporal, the
    // content is transformed back to the original Payload sent in this command.
    temporal.api.common.v1.Payload input = 4;
    // Schedule-to-close timeout for this operation.
    // Indicates how long the caller is willing to wait for operation completion.
    // Calls are retried internally by the server.
    // (-- api-linter: core::0140::prepositions=disabled
    //     aip.dev/not-precedent: "to" is used to indicate interval. --)
    google.protobuf.Duration schedule_to_close_timeout = 5;

    // Header to attach to the Nexus request.
    // Users are responsible for encrypting sensitive data in this header as it is stored in workflow history and
    // transmitted to external services as-is.
    // This is useful for propagating tracing information.
    // Note these headers are not the same as Temporal headers on internal activities and child workflows, these are
    // transmitted to Nexus operations that may be external and are not traditional payloads.
    map<string, string> nexus_header = 6;
}

message RequestCancelNexusOperationCommandAttributes {
    // The `NEXUS_OPERATION_SCHEDULED` event ID (a unique identifier) for the operation to be canceled.
    // The operation may ignore cancellation and end up with any completion state.
    int64 scheduled_event_id = 1;
}

message Command {
    temporal.api.enums.v1.CommandType command_type = 1;
    // Metadata on the command. This is sometimes carried over to the history event if one is
    // created as a result of the command. Most commands won't have this information, and how this
    // information is used is dependent upon the interface that reads it.
    //
    // Current well-known uses:
    //  * start_child_workflow_execution_command_attributes - populates
    //    temporal.api.workflow.v1.WorkflowExecutionInfo.user_metadata where the summary and details
    //    are used by user interfaces to show fixed as-of-start workflow summary and details.
    //  * start_timer_command_attributes - populates temporal.api.history.v1.HistoryEvent for timer
    //    started where the summary is used to identify the timer.
    temporal.api.sdk.v1.UserMetadata user_metadata = 301;
    // The command details. The type must match that in `command_type`.
    oneof attributes {
        ScheduleActivityTaskCommandAttributes schedule_activity_task_command_attributes = 2;
        StartTimerCommandAttributes start_timer_command_attributes = 3;
        CompleteWorkflowExecutionCommandAttributes complete_workflow_execution_command_attributes = 4;
        FailWorkflowExecutionCommandAttributes fail_workflow_execution_command_attributes = 5;
        RequestCancelActivityTaskCommandAttributes request_cancel_activity_task_command_attributes = 6;
        CancelTimerCommandAttributes cancel_timer_command_attributes = 7;
        CancelWorkflowExecutionCommandAttributes cancel_workflow_execution_command_attributes = 8;
        RequestCancelExternalWorkflowExecutionCommandAttributes request_cancel_external_workflow_execution_command_attributes = 9;
        RecordMarkerCommandAttributes record_marker_command_attributes = 10;
        ContinueAsNewWorkflowExecutionCommandAttributes continue_as_new_workflow_execution_command_attributes = 11;
        StartChildWorkflowExecutionCommandAttributes start_child_workflow_execution_command_attributes = 12;
        SignalExternalWorkflowExecutionCommandAttributes signal_external_workflow_execution_command_attributes = 13;
        UpsertWorkflowSearchAttributesCommandAttributes upsert_workflow_search_attributes_command_attributes = 14;
        ProtocolMessageCommandAttributes protocol_message_command_attributes = 15;
        // 16 is available for use - it was used as part of a prototype that never made it into a release
        ModifyWorkflowPropertiesCommandAttributes modify_workflow_properties_command_attributes = 17;

        ScheduleNexusOperationCommandAttributes schedule_nexus_operation_command_attributes = 18;
        RequestCancelNexusOperationCommandAttributes request_cancel_nexus_operation_command_attributes = 19;
    }
}
