// 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 models.controller;
option go_package = "gitlab.com/rigetti/share/service-model/golang/controller";
import "controller/readout.proto";

// An EncryptedControllerJob includes the configuration necessary to execute an instance of
// the contained job data on control hardware in encrypted format.
message EncryptedControllerJob {

    // Encrypted form of ControllerJob.
    bytes job = 1;

    // Information about the means by which `inner` was encrypted.
    .models.controller.JobEncryption encryption = 2;

    reserved 3;
    reserved "memory_values";}

// Information about the means by which a ControllerJob was encrypted.
message JobEncryption {

    // Opaque identifier for the key to use in decryption
    string key_id = 1;

    // If relevant, the nonce to use in decryption
    bytes nonce = 2;
}
message JobExecutionConfiguration {

    // Memory values to be patched into the program by the Controller Service prior to execution.
    // The string key is used to match the name of the memory region as defined in the
    // InstrumentProgram. The type of the DataValue must match the defined type of the region.
    map<string, .models.controller.DataValue> memory_values = 3;
}

// The value of the data to insert into memory corresponding to a MemoryRegion.
message DataValue {
    oneof value {

        // Binary value, corresponding to both BIT and OCTET data types in Quil.
        .models.controller.BinaryDataValue binary = 101;

        // Signed integer value, corresponding to INTEGER in Quil.
        .models.controller.IntegerDataValue integer = 102;

        // Real number value, corresponding to REAL in Quil.
        .models.controller.RealDataValue real = 103;
    }
}

// Binary value, corresponding to both BIT and OCTET data types in Quil.
message BinaryDataValue {
    bytes data = 1;
}

// Signed integer value, corresponding to INTEGER in Quil.
message IntegerDataValue {
    repeated int64 data = 1;
}

// Real number value, corresponding to REAL in Quil.
message RealDataValue {
    repeated double data = 1;
}

// A ControllerJobExecutionResult includes the result data from a single
// execution of a ControllerJob.
message ControllerJobExecutionResult {

    // The contents of each memory region, keyed on region name
    map<string, .models.controller.DataValue> memory_values = 1;

    // The contents of readout data published by the readout transformation
    // pipeline, keyed on the node ID of the publishing readout transformation
    // node.
    map<string, .models.controller.ReadoutValues> readout_values = 2;
    .models.controller.ControllerJobExecutionResult.Status status = 3;

    // Optional message providing context to the result's status.
    optional string status_message = 4;

    // Duration (µs) job held exclusive access to control hardware.
    uint64 execution_duration_microseconds = 5;
    enum Status {
        UNKNOWN = 0;
        SUCCESS = 1;

        // Failure state caused by an error in the service.
        SERVICE_FAILURE = 2;

        // Failure state caused by user.
        USER_FAILURE = 3;

        // Job was canceled by user before execution completed.
        USER_CANCELLATION = 4;
    }
}
