// Copyright 2023 Rigetti Computing
//
// 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 services.controller;
option go_package = "gitlab.com/rigetti/share/service-model/golang/controller";
import "controller/job.proto";

// A request to execute multiple ControllerJobs as if they were sent as separate requests.
// Note that the job execution IDs will be returned in the same order as the requests,
// but execution itself may occur out of that order depending on executor configuration.
message BatchExecuteControllerJobsRequest {
    repeated .services.controller.ExecuteControllerJobRequest requests = 1;
}
message BatchExecuteControllerJobsResponse {
    repeated .services.controller.ExecuteControllerJobResponse responses = 1;
}

// A request to execute a given ControllerJob on a specific target with one or more configurations.
// Note that a request to execute a job with zero configurations will result in an error.
message ExecuteControllerJobRequest {

    // One or more configurations against which to execute the provided job.
    //
    // The response will include one `job_execution_id` for each entry in this list,
    // each corresponding to its configuration in the same order.
    repeated .models.controller.JobExecutionConfiguration execution_configurations = 3;
    oneof job {
        .models.controller.EncryptedControllerJob encrypted = 201;
    }
    oneof target {
        // Required by the gateway to forward requests to the correct execution host.

        string quantum_processor_id = 101;
        string endpoint_id = 102;
    }
}
message ExecuteControllerJobResponse {

    // One execution ID per input JobExecutionConfiguration, in the same order as the input.
    repeated string job_execution_ids = 1;
}
message GetControllerJobResultsRequest {

    // Which Controller Job execution to query for results
    string job_execution_id = 1;
    oneof target {
        // Required by the gateway to forward requests to the correct execution host.

        string quantum_processor_id = 101;
        string endpoint_id = 102;
    }
}
message GetControllerJobResultsResponse {
    .models.controller.ControllerJobExecutionResult result = 1;
}

// Cancel all given jobs that have yet to begin executing.
// This endpoint is *not* atomic, and will attempt to cancel every job even
// when some jobs cannot be canceled. A job can be canceled only if it
// has not yet started executing.
//
// Success response indicates only that the request was received. Cancellation
// is not guaranteed, as it is based on job state at time of cancellation, and is
// completed on a best-effort basis.
message CancelControllerJobsRequest {
    repeated string job_ids = 1;
}
message CancelControllerJobsResponse {
}
message GetControllerJobStatusRequest {
    string job_id = 1;
}
message GetControllerJobStatusResponse {
    .services.controller.GetControllerJobStatusResponse.Status status = 1;
    enum Status {
        UNKNOWN = 0;
        QUEUED = 1;
        RUNNING = 2;
        SUCCEEDED = 3;
        FAILED = 4;
        CANCELED = 5;
    }
}

service Controller {

    rpc ExecuteControllerJob(.services.controller.ExecuteControllerJobRequest) returns (.services.controller.ExecuteControllerJobResponse) {
    }

    rpc BatchExecuteControllerJobs(.services.controller.BatchExecuteControllerJobsRequest) returns (.services.controller.BatchExecuteControllerJobsResponse) {
    }

    rpc GetControllerJobResults(.services.controller.GetControllerJobResultsRequest) returns (.services.controller.GetControllerJobResultsResponse) {
    }

    rpc CancelControllerJobs(.services.controller.CancelControllerJobsRequest) returns (.services.controller.CancelControllerJobsResponse) {
    }

    rpc GetControllerJobStatus(.services.controller.GetControllerJobStatusRequest) returns (.services.controller.GetControllerJobStatusResponse) {
    }
}
