//
// Copyright 2022 The Project Oak Authors
//
// 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 oak.functions;

import "proto/crypto/crypto.proto";
import "proto/attestation/evidence.proto";
import "proto/micro_rpc/options.proto";

service OakFunctions {
  // Initializes the service and remote attestation keys.
  //
  // method_id: 0
  rpc Initialize(InitializeRequest) returns (InitializeResponse) {
    option (.oak.micro_rpc.method_id) = 0;
  }

  // Handles an invocation coming from a client.
  //
  // method_id: 1
  rpc HandleUserRequest(InvokeRequest) returns (InvokeResponse) {
    option (.oak.micro_rpc.method_id) = 1;
  }

  // Extends the next lookup data by the given chunk of lookup data. Only
  // after the sender calls finishes building the next lookup data, the receiver
  // replaces the current lookup data with the next lookup data, and only then
  // chunk is will be served in lookups.
  //
  // method_id: 2
  rpc ExtendNextLookupData(ExtendNextLookupDataRequest)
      returns (ExtendNextLookupDataResponse) {
    option (.oak.micro_rpc.method_id) = 2;
  }

  // Finishes building the next lookup data with the given chunk of lookup data.
  // The receiver replaces the current lookup data and the next lookup data will
  // be served in lookups.
  //
  // method_id: 3
  rpc FinishNextLookupData(FinishNextLookupDataRequest)
      returns (FinishNextLookupDataResponse) {
    option (.oak.micro_rpc.method_id) = 3;
  }

  // Aborts building the next lookup data.option
  //
  // method_id: 4
  rpc AbortNextLookupData(Empty) returns (AbortNextLookupDataResponse) {
    option (.oak.micro_rpc.method_id) = 4;
  }

  // Streaming version combining `ExtendNextLookupData` and
  // `FinishNextLookupData`.
  //
  // This is mainly for use with gRPC, as microRPC doesn't support streaming.
  //
  // method_id: 5
  rpc StreamLookupData(stream LookupDataChunk)
      returns (FinishNextLookupDataResponse) {
    option (.oak.micro_rpc.method_id) = 5;
  }

  // Reserves additional capacity for entries in the lookup table.
  //
  // It should be called before `ExtendNextLookupData`/`StreamLookupData` to
  // reduce the number of memory allocations, but it's not mandatory to call
  // this RPC.
  //
  // method_id: 6
  rpc Reserve(ReserveRequest) returns (ReserveResponse) {
    option (.oak.micro_rpc.method_id) = 6;
  }
}

message InitializeRequest {
  bytes wasm_module = 1;
  uint32 constant_response_size = 2;
}

message InitializeResponse {
  oak.attestation.v1.Evidence evidence = 2;
}

message InvokeRequest {
  oak.crypto.v1.EncryptedRequest encrypted_request = 2;
}

message InvokeResponse {
  oak.crypto.v1.EncryptedResponse encrypted_response = 2;
}

message LookupDataEntry {
  bytes key = 1;
  bytes value = 2;
}

message LookupDataChunk {
  repeated LookupDataEntry items = 1;
}

// If the definition of ExtendNextLookupData changes, the estimation of the size
// when serialized in the Oak Functions Launcher needs to change, too.
message ExtendNextLookupDataRequest {
  oneof data {
    LookupDataChunk chunk = 1;

    // Experimental: a serialized array of varint-prefixed `LookupDataEntry`
    // values. See
    // https://docs.rs/prost/latest/prost/fn.decode_length_delimiter.html for
    // more details; the hope here is that by serializing one entry at a time we
    // can be more efficient.
    bytes length_delimited_entries = 2 [ctype = CORD];
  }
}

message ExtendNextLookupDataResponse {}

message FinishNextLookupDataRequest {}

message FinishNextLookupDataResponse {}

message AbortNextLookupDataResponse {}

message Empty {}

message ReserveRequest {
  uint64 additional_entries = 1;
}

message ReserveResponse {}
