/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * 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 android.virtualdevice.proto;

option java_package = "android.virtualdevice.proto";

option java_multiple_files = true;
option java_generic_services = true;

// Request to lease a virtual device with specific hardware and software
// configurations.
message LeaseAvdDeviceRequest {
  // Specifications for the device to be leased.
  VirtualDeviceSpec device_specification = 1;
  // User account associated with the device lease.
  string accounting_user = 2;
}

// Response containing details of the leased virtual device.
message LeaseAvdDeviceResponse {
  // Specifications of the leased device. This can be null or empty if there's
  // an error.
  VirtualDeviceSpec leased_device_spec = 1;
  // Error details if the leasing process fails. This should be null or empty on
  // success.
  ErrorDetails error = 2;
}

// Request to release a virtual device that was previously leased.
message ReleaseAvdDeviceRequest {
  // Specifications of the device to be released.
  VirtualDeviceSpec device_specification = 1;
}

// Response indicating the status of the virtual device release operation.
message ReleaseAvdDeviceResponse {
  // Error details if the release process fails. This should be null or empty on
  // success.
  ErrorDetails error = 1;
}

// Specifications defining a virtual device.
message VirtualDeviceSpec {
  // Base specifications for a Cuttlefish device.
  CuttlefishBuildInfo cuttlefish_spec = 1;
  // Options for launching the device.
  CuttlefishLaunchOptions launch_options = 2;
  // Network ports exposed by the virtual device.
  repeated ExposedPort ports = 3;
  // Session ID associated with the device lease.
  string session_id = 4;
  // URL for remote access to the device.
  string server_url = 5;
  // Duration of the lease in seconds.
  uint32 lease_length_secs = 6;
  // Hardware size of the device instance(GENERIC_CF, GENERIC_CF_LARGE,
  // GENERIC_CF_EXTRA_LARGE)
  string instance_size = 7;
}

// Detailed specifications of a Cuttlefish virtual device.
message CuttlefishBuildInfo {
  // Build ID of the Cuttlefish device.
  string build_id = 1;
  // Build target of the Cuttlefish device.
  string build_target = 2;
  // Build branch of the Cuttlefish device.
  string build_branch = 3;
}

// Options to customize the launch of a Cuttlefish device.
message CuttlefishLaunchOptions {
  // Extra arguments to pass during launch.
  repeated string extra_launch_args = 1;
}

// Description of network ports exposed by the virtual device.
message ExposedPort {
  // Port number on the remote host machine.
  uint32 host_port = 1;
  // Corresponding port in local environment.
  uint32 guest_port = 2;
  // Network protocol used (e.g. ADB).
  string protocol_type = 3;
}

// Request to set up a connection for a leased virtual device.
message SetupDeviceConnectionRequest {
  // Specifications of the device to be connected.
  VirtualDeviceSpec device_specification = 1;
}

// Response to a request for setting up a device connection.
message SetupDeviceConnectionResponse {
  // Specifications of the connected device. This can be null or empty if
  // there's an error.
  VirtualDeviceSpec device_specification = 1;

  // Error details if the connection setup fails. This should be null or empty
  // on success.
  ErrorDetails error = 2;
}

// Request to retrieve logs from a specific virtual device.
message PullLogsRequest {
  // Type of log to be retrieved.
  LogType log_type = 1;
  // Specifications of the device from which logs are to be pulled.
  VirtualDeviceSpec device_specification = 2;
}

// Response containing logs retrieved from a virtual device.
message PullLogsResponse {
  // Error details if the log retrieval process fails. This should be null or
  // empty on success.
  ErrorDetails error_details = 1;
  // Location where the logs are stored or accessible locally after being
  // successfully pulled from the virtual device service. This field is
  // populated only if the retrieval is successful. It typically contains a
  // local file path.
  string log_location = 2;
}

// Detailed information about errors encountered in using the virtual device
// component.
message ErrorDetails {
  // Human-readable description of the error.
  string message = 1;
  // Numeric error code for categorizing the error type.
  int32 code = 2;
}

// Enum to specify the type of log to be retrieved.
enum LogType {
  // Default value, unspecified log type.
  LOG_TYPE_UNSPECIFIED = 0;
  // General log from the Cuttlefish instance.
  GENERAL_CF_LOG = 1;
  // Kernel log from the virtual device hosting machine.
  HOST_KERNEL_LOG = 2;
  // Log from the host orchestrator.
  HOST_ORCHESTRATOR_LOG = 3;
}

// VirtualDeviceManagerInterface provides an interface for managing virtual
// devices in a virtual device service, including leasing, releasing, and
// managing device connections.
service VirtualDeviceManagerInterface {
  // Leases a virtual device based on the specified requirements and returns
  // VirtualDeviceSpec with the leased device details.
  rpc LeaseAvdDevice(LeaseAvdDeviceRequest) returns (LeaseAvdDeviceResponse) {}

  // Releases a previously leased virtual device. Returns an error if failed to
  // release the device.
  rpc ReleaseAvdDevice(ReleaseAvdDeviceRequest)
      returns (ReleaseAvdDeviceResponse) {}

  // Sets up a connection for a leased virtual device.
  rpc SetupDeviceConnection(SetupDeviceConnectionRequest)
      returns (SetupDeviceConnectionResponse) {}

  // Retrieves specified logs from a leased virtual device.
  rpc PullLogs(PullLogsRequest) returns (PullLogsResponse) {}
}
