syntax = "proto3";

option go_package = "github.com/hatchet-dev/hatchet/internal/services/shared/proto/v1";

package v1;

import "google/protobuf/timestamp.proto";
import "v1/shared/condition.proto";
import "v1/shared/trigger.proto";

// AdminService represents a set of RPCs for admin management of tasks, workflows, etc.
service AdminService {
    rpc PutWorkflow(CreateWorkflowVersionRequest) returns (CreateWorkflowVersionResponse);
    rpc CancelTasks(CancelTasksRequest) returns (CancelTasksResponse);
    rpc ReplayTasks(ReplayTasksRequest) returns (ReplayTasksResponse);
    rpc TriggerWorkflowRun(TriggerWorkflowRunRequest) returns (TriggerWorkflowRunResponse);
    rpc GetRunDetails(GetRunDetailsRequest) returns (GetRunDetailsResponse);
    rpc BranchDurableTask(BranchDurableTaskRequest) returns (BranchDurableTaskResponse);
}

message CancelTasksRequest {
    repeated string external_ids = 1; // a list of external UUIDs
    optional TasksFilter filter = 2;
}

message ReplayTasksRequest {
    repeated string external_ids = 1; // a list of external UUIDs
    optional TasksFilter filter = 2;
}

message TasksFilter {
    repeated string statuses = 1;
    google.protobuf.Timestamp since = 2;
    optional google.protobuf.Timestamp until = 3;
    repeated string workflow_ids = 4;
    repeated string additional_metadata = 5;
}

message CancelTasksResponse {
    repeated string cancelled_tasks = 1;
}

message ReplayTasksResponse {
    repeated string replayed_tasks = 1;
}

message TriggerWorkflowRunRequest {
    string workflow_name = 1;
    bytes input = 2;
    bytes additional_metadata = 3;
    optional int32 priority = 4;
    map<string, DesiredWorkerLabels> desired_worker_labels = 5;
}

message TriggerWorkflowRunResponse {
    string external_id = 1;
}

message BranchDurableTaskRequest {
    string task_external_id = 1; // (required) the external id (uuid) of the durable task
    int64 node_id = 2; // (required) the node id to branch from
    int64 branch_id = 3; // (required) the branch id to branch from
}

message BranchDurableTaskResponse {
    string task_external_id = 1; // the external id of the durable task
    int64 node_id = 2; // the node id of the new entry
    int64 branch_id = 3; // the branch id of the new entry
}

enum StickyStrategy {
    SOFT = 0;
    HARD = 1;
}

enum RateLimitDuration {
    SECOND = 0;
    MINUTE = 1;
    HOUR = 2;
    DAY = 3;
    WEEK = 4;
    MONTH = 5;
    YEAR = 6;
}

enum RunStatus {
    QUEUED = 0;
    RUNNING = 1;
    COMPLETED = 2;
    FAILED = 3;
    CANCELLED = 4;
    EVICTED = 5;
}


// CreateWorkflowVersionRequest represents options to create a workflow version.
message CreateWorkflowVersionRequest {
    string name = 1; // (required) the workflow name
    string description = 2; // (optional) the workflow description
    string version = 3; // (optional) the workflow version
    repeated string event_triggers = 4; // (optional) event triggers for the workflow
    repeated string cron_triggers = 5; // (optional) cron triggers for the workflow
    repeated CreateTaskOpts tasks = 6; // (required) the workflow jobs

    // Deprecated: use concurrency_arr instead
    Concurrency concurrency = 7; // (optional) the workflow concurrency options
    optional string cron_input = 8; // (optional) the input for the cron trigger
    optional CreateTaskOpts on_failure_task = 9; // (optional) the job to run on failure
    optional StickyStrategy sticky = 10; // (optional) the sticky strategy for assigning tasks to workers
    optional int32 default_priority = 11; // (optional) the default priority for the workflow
    repeated Concurrency concurrency_arr = 12; // (optional) the workflow concurrency options
    repeated DefaultFilter default_filters = 13; // (optional) the default filters for the workflow
    optional bytes input_json_schema = 14; // (optional) the JSON schema for the workflow input
}


message DefaultFilter {
    string expression = 1; // (required) the CEL expression for the filter
    string scope = 2; // (required) the scope of the filter
    optional bytes payload = 3; // (optional) the payload for the filter, if any. A JSON object as a string.
}

enum ConcurrencyLimitStrategy {
    CANCEL_IN_PROGRESS = 0;
    DROP_NEWEST = 1; // deprecated
    QUEUE_NEWEST = 2; // deprecated
    GROUP_ROUND_ROBIN = 3;
    CANCEL_NEWEST = 4;
}

message Concurrency {
    string expression = 1; // (required) the expression to use for concurrency
    optional int32 max_runs = 2; // (optional) the maximum number of concurrent workflow runs, default 1
    optional ConcurrencyLimitStrategy limit_strategy = 3; // (optional) the strategy to use when the concurrency limit is reached, default CANCEL_IN_PROGRESS
}


// CreateTaskOpts represents options to create a task.
message CreateTaskOpts {
    string readable_id = 1; // (required) the task name
    string action = 2; // (required) the task action id
    string timeout = 3; // (optional) the task timeout
    string inputs = 4; // (optional) the task inputs, assuming string representation of JSON
    repeated string parents = 5; // (optional) the task parents. if none are passed in, this is a root task
    int32 retries = 6; // (optional) the number of retries for the task, default 0
    repeated CreateTaskRateLimit rate_limits = 7; // (optional) the rate limits for the task
    map<string, DesiredWorkerLabels> worker_labels = 8; // (optional) the desired worker affinity state for the task
    optional float backoff_factor = 9; // (optional) the retry backoff factor for the task
    optional int32 backoff_max_seconds = 10; // (optional) the maximum backoff time for the task
    repeated Concurrency concurrency = 11; // (optional) the task concurrency options
    optional TaskConditions conditions = 12; // (optional) the task conditions for creating the task
    optional string schedule_timeout = 13; // (optional) the timeout for the schedule
    bool is_durable = 14; // (optional) whether the task is durable
    map<string, int32> slot_requests = 15; // (optional) slot requests (slot_type -> units)
}

message CreateTaskRateLimit {
    string key = 1; // (required) the key for the rate limit
    optional int32 units = 2; // (optional) the number of units this task consumes
    optional string key_expr = 3; // (optional) a CEL expression for determining the rate limit key
    optional string units_expr = 4; // (optional) a CEL expression for determining the number of units consumed
    optional string limit_values_expr = 5; // (optional) a CEL expression for determining the total amount of rate limit units
    optional RateLimitDuration duration = 6; // (optional) the default rate limit window to use for dynamic rate limits
}

// CreateWorkflowVersionResponse represents the response after creating a workflow version.
message CreateWorkflowVersionResponse {
    string id = 1;
    string workflow_id = 2;
}

message GetRunDetailsRequest {
    string external_id = 1; // (required) the external id (uuid) of the workflow run
}

message TaskRunDetail {
    string external_id = 1; // the external id (uuid) of the task run
    RunStatus status = 2; // the status of the task run
    optional string error = 3; // (optional) error message from the task run, if any
    optional bytes output = 4; // (optional) the output payload for the task run
    string readable_id = 5; // the readable id of the task
    bool is_evicted = 6; // whether the task has been evicted from a worker (status will be RUNNING)
}

message GetRunDetailsResponse {
    bytes input = 1; // the input payload for the workflow run
    RunStatus status = 2; // the status of the workflow run
    map<string, TaskRunDetail> task_runs = 3; // map of task run external ids to their details
    bool done = 4; // indicates if the workflow run is done
    bytes additional_metadata = 5; // (optional) additional metadata for the workflow run
    bool is_evicted = 6; // whether any task in this run has been evicted
}
