syntax = "proto3";

package hillab.v4;

import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

/************* service BeamProfiler start *************/

// Represents a value that can hold different types.
message Value {
  oneof value {
    bool bool_value = 1;
    int32 int_value = 2;
    float float_value = 3;
    string string_value = 4;
  }
}

// Request message for setting a specific value by key.
message SetRequest {
  // The key that identifies the value being set.
  string key = 1;

  // The value to be set for the specified key.
  Value value = 2;
}

// Request message for retrieving a value by key.
message GetRequest {
  // The key that identifies the value being retrieved.
  string key = 1;
}

// Response message for getting the value of a specified key.
message GetResponse {
  // The key for which the value is returned.
  string key = 1;

  // The value corresponding to the key.
  Value value = 2;

  // Optional unit for the value.
  optional string unit = 3;

  // Optional minimum value that the key can hold.
  optional Value min_value = 4;

  // Optional maximum value that the key can hold.
  optional Value max_value = 5;
}

// Represents the profile data of a beam at a specific index.
message BeamProfile {
  // The index of the beam profile.
  int32 index = 1;

  // The most recent value of the beam at this index.
  double latest_value = 2;

  // The average value of the beam profile.
  double average = 3;

  // The standard deviation of the beam profile values.
  double standard_deviation = 4;
}

// Represents a stream of beam profiles over time.
message BeamProfileStream {
  // The timestamp when the beam profile data is recorded.
  google.protobuf.Timestamp time = 1;

  // A list of beam profiles recorded at the given timestamp.
  repeated BeamProfile beam_profiles = 2;
}

// BeamProfiler service that allows retrieving and setting beam profile data.
service BeamProfiler {
  // Retrieves the value named given key.
  // Returns: 
  // - Status "OK" for successful.
  // - Status "FAILED_PRECONDITION" for failure since various reasons. See message for more detail.
  // - Status "NOT_FOUND" for failure since given key is undefined.
  // - Status "INTERNAL" for failure since system error. 
  rpc Get(GetRequest) 
  returns (GetResponse) {}

  // Modifies the value named given key.
  // Returns: 
  // - Status "OK" for successful.
  // - Status "FAILED_PRECONDITION" for failure since various reasons. See message for more detail.
  // - Status "INVALID_ARGUMENT" for failure since various reasons. See message for more detail.
  // - Status "NOT_FOUND" for failure since given key is undefined.
  // - Status "INTERNAL" for failure since system error.
  rpc Set(SetRequest) 
  returns (google.protobuf.Empty) {}

  // Initializes the accumulated profiled data of all fields.
  // Returns:
  // - Status "OK" for successful.
  rpc ResetData(google.protobuf.Empty) 
  returns (google.protobuf.Empty) {}

  // Retrieves the stream object for obtaining the beam profile.
  // Returns: 
  // - Status "OK" for successful.
  rpc MonitorBeamProfile(google.protobuf.Empty) 
  returns (stream BeamProfileStream) {}
}

/************* service BeamProfiler end *************/



/************* service System start *************/

// Response containing the app information.
message AppInfoResponse {
  // Version of the app.
  string version = 1;
}

// Request to load, save, add, or remove a specific setting by name.
message SettingRequest {
  // The name of the setting.
  // Must match a registered setting name for operations like "Load" or "Remove".
  string name = 1;
}

// Response containing the name of the current loaded setting.
message SettingResponse {
  // The name of the currently loaded setting.
  string name = 1;
}

// Response containing the list of all registered settings.
message SettingListResponse {
  // List of registered setting names.
  repeated string name_list = 1;
}

// Information about a device, including its alias and serial number.
message DeviceInfo {
  // The user-defined alias for the device.
  string alias = 1;
  
  // The unique serial number of the device.
  string serial_number = 2;
}

// Response containing a list of available devices.
message DeviceInfoList {
  // List of devices, each containing alias and serial number.
  repeated DeviceInfo devices = 1;
}

// Request to connect to a specific device using its serial number.
message ConnectDeviceRequest {
  // The serial number of the target device to connect.
  string serial_number = 1;
}

// Request to configure or control the image stream server.
message ImageStreamServerRequest {
  // Request to start or stop the stream.
  // - true: Start the stream.
  // - false: Stop the stream.
  // If not provided, the `running` status will remain unchanged.
  optional bool running = 1;

  // Update the Maximum Transmission Unit (MTU) for RTP packets.
  // Range: 512 to 1500 bytes.
  // If not provided, the `mtu` status will remain unchanged.
  optional int32 mtu = 2; 

  // Update the downscaling factor for the streamed video resolution.
  // The resolution is calculated as: `origin_size / pow(2, downscale)`.
  // Range: 0 to 4.
  // Example:
  // - downscale=0 -> resolution = original_size. 
  // - downscale=1 -> resolution = original_size / 2. 
  // - downscale=2 -> resolution = original_size / 4.
  // - downscale=3 -> resolution = original_size / 8. 
  // - downscale=4 -> resolution = original_size / 16. 
  // If not provided, the current `downscale` value will remain unchanged.
  optional int32 downscale = 3;

  // Request to enable or disable automatic stream startup.
  // - true: Enable automatic stream startup when camera streaming started.
  // - false: Disable automatic stream startup.
  // If not provided, the `auto_running` setting will remain unchanged.
  optional bool auto_running = 4;
}

// Response containing information about the image stream server.
message ImageStreamServerResponse {
  // The IPv4 IP address of the server. (e.g., "192.168.1.1")
  string ip = 1;

  // The port number used for the stream.
  int32 port = 2;

  // Maximum Transmission Unit (MTU) for RTP packets.
  // Range: 512 to 1500 bytes.
  int32 mtu = 3;  

  // Downscaling factor for the streamed video resolution.
  // The resolution is calculated as: `origin_size / pow(2, downscale)`.
  // Range: 0 to 4.
  // Example:
  // - downscale=0 -> resolution = original_size. 
  // - downscale=1 -> resolution = original_size / 2. 
  // - downscale=2 -> resolution = original_size / 4.
  // - downscale=3 -> resolution = original_size / 8. 
  // - downscale=4 -> resolution = original_size / 16. 
  // If not provided, the current `downscale` value will remain unchanged.
  int32 downscale = 4;

  // Indicates whether the stream is currently running.
  bool running = 5;

  // Indicates whether the stream is configured to start automatically when camera streaming started.
  bool auto_running = 6;

  // The SDP (Session Description Protocol) string for the stream.
  // Used for configuring media sessions.
  string sdp = 7;
}

// Enum representing the type of a system log message.
enum SystemLogType {
  // Informational log messages, such as system events or status updates.
  SYSTEMLOGTYPE_INFO = 0;

  // Error log messages, such as system failures or critical issues.
  SYSTEMLOGTYPE_ERROR = 1;
}

// Represents a system log entry in the system log stream.
message SystemLogStream {
  // The timestamp when the log message was generated.
  google.protobuf.Timestamp time = 1;

  // The type of the log message (informational or error).
  SystemLogType type = 2;

  // The content of the log message.
  string message = 3;
}

service System {
  rpc GetAppInfo(google.protobuf.Empty)
  returns (AppInfoResponse) {}

  // Retrieves registered setting list.
  // Returns: 
  // - Status "OK" and response indicating the setting name list.
  rpc GetSettingList(google.protobuf.Empty)
  returns (SettingListResponse) {}

  // Retrieves the loaded setting.
  // Returns: 
  // - Status "OK" and response indicating the loaded setting name.
  rpc GetCurrentSetting(google.protobuf.Empty)
  returns (SettingResponse) {}

  // Loads setting. All system properties are applied as loaded settings, but information of gRPC host and Image Stream hosts is not loaded.
  // Returns: 
  // - Status "OK" for successful.
  // - Status "FAILED_PRECONDITION" for failure since the setting name is not exist in registered setting list.
  rpc LoadSetting(SettingRequest)
  returns (google.protobuf.Empty) {}

  // Saves setting. All system properties are saved in the current setting, including information of gRPC hosts and Image Stream hosts.
  // Returns: 
  // - Status "OK" for successful saving the setting.
  rpc SaveSetting(google.protobuf.Empty)
  returns (google.protobuf.Empty) {}

  // Adds available setting. All system properties will be saved with new setting.
  // This works like "Save as".
  // If the setting already exist, the existing setting will be overwritten.
  // Returns: 
  // - Status "OK" for successful.
  rpc AddSetting(SettingRequest)
  returns (google.protobuf.Empty) {}

  // Removes setting from the registered setting list.
  // Returns: 
  // - Status "OK" for successful.
  // - Status "FAILED_PRECONDITION" for failure since target setting is loaded or not exist in registered setting list.
  rpc RemoveSetting(SettingRequest)
  returns (google.protobuf.Empty) {}

  // Retrieves the available device list.
  // Returns: 
  // - Status "OK" and response indicating the available device list.
  rpc GetDeviceList(google.protobuf.Empty)
  returns (DeviceInfoList) {}

  // Connects last connected device. 
  // Returns: 
  // - Status "OK" for successful.
  // - Status "FAILED_PRECONDITION" for failure.
  rpc ConnectLastDevice(google.protobuf.Empty)
  returns (google.protobuf.Empty) {}

  // Connects device which of serial number is given. 
  // Returns: 
  // - Status "OK" for successful.
  // - Status "FAILED_PRECONDITION" for failure.
  rpc ConnectDevice(ConnectDeviceRequest)
  returns (google.protobuf.Empty) {}

  // Disconnects the device.
  // Returns: 
  // - Status "OK" for successful.
  rpc DisconnectDevice(google.protobuf.Empty)
  returns (google.protobuf.Empty) {}

  // Retrieves image stream server information for raw image.
  // Returns: 
  // - Status "OK" and response indicating the image stream information.
  rpc GetRawImageStreamServerInfo(google.protobuf.Empty)
  returns (ImageStreamServerResponse) {}

  // Retrieves image stream server information for profiled image.
  // Returns: 
  // - Status "OK" and response indicating the image stream information.
  rpc GetProfiledImageStreamServerInfo(google.protobuf.Empty)
  returns (ImageStreamServerResponse) {}

  // Starts/stops image stream server for raw image and/or modifies options. 
  // The server's URL (IP and Port) cannot be changed with gRPC.
  // Note that the camera must be streaming to start the stream server.
  // Returns: 
  // - Status "OK" for successful.
  // - Status "INVALID ARGUMENT" for failure since some values are out of range.
  // - Status "FAILED_PRECONDITION" for indicating that the stream cannot be started, or failure for changing some value since the server is running.
  rpc SetRawImageStreamServer(ImageStreamServerRequest)
  returns (google.protobuf.Empty) {}

  // Starts/stops image stream server for raw image and/or modifies options. 
  // The server's URL (IP and Port) cannot be changed with gRPC.
  // Note that the camera must be streaming to start the stream server.
  // Returns: 
  // - Status "OK" for successful.
  // - Status "INVALID ARGUMENT" for failure since some values are out of range.
  // - Status "FAILED_PRECONDITION" for indicating that the stream cannot be started, or failure for changing some value since the server is running.
  rpc SetProfiledImageStreamServer(ImageStreamServerRequest)
  returns (google.protobuf.Empty) {}

  // Retrieves the stream object for obtaining the system log message.
  // Returns: 
  // - Status "OK" for successful.
  rpc MonitorSystemLog(google.protobuf.Empty)
  returns (stream SystemLogStream) {}
}

/************* service System end *************/