/*
 *  Copyright (c) 2026, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

syntax = "proto3";

package nexus;

/**
 * Represents an event occurring within the simulation.
 */
message SimulationEvent {
  uint64 timestamp_us = 1; // Simulation time in microseconds
  oneof event {
    NodeUpdate node_update = 2;       // Node state or position update
    LinkUpdate link_update = 3;       // Link connectivity change
    PacketCaptured packet_captured = 4; // Radio packet capture
    Heartbeat heartbeat = 5;           // Periodic keep-alive and clock sync
  }
}

/**
 * Periodic event sent to maintain the gRPC stream and sync simulation time.
 */
message Heartbeat {}

/**
 * Detailed Thread device roles.
 */
enum NodeRole {
  ROLE_UNKNOWN = 0;
  ROLE_DISABLED = 1;
  ROLE_DETACHED = 2;
  ROLE_CHILD = 3;
  ROLE_ROUTER = 4;
  ROLE_LEADER = 5;
  ROLE_REED = 6; // Router Eligible End Device
  ROLE_FED = 7;  // Full End Device
  ROLE_MED = 8;  // Minimal End Device
  ROLE_SED = 9;  // Sleepy End Device
}

/**
 * Information about a node's current state and position.
 */
message NodeUpdate {
  uint32 node_id = 1;
  NodeRole role = 2;
  uint32 rloc16 = 3;
  float x = 4;
  float y = 5;
}

/**
 * Information about a radio link between two nodes.
 */
message LinkUpdate {
  uint32 source_node_id = 1;
  uint32 destination_node_id = 2;
  bool is_active = 3;
  float link_quality = 4; // e.g., RSSI or link quality index
}

/**
 * Captured radio packet data.
 */
message PacketCaptured {
  uint32 source_node_id = 1;
  uint32 destination_node_id = 2;
  string protocol = 3;      // Human-readable protocol name (e.g., "IEEE 802.15.4 ACK")
  string summary = 4;       // Short summary of packet content
  bytes raw_payload = 5;    // Raw PSDU data
  string decoded_info = 6;  // Reserved for future use
}

message ResetRequest {}
message ResetResponse {}

/**
 * Request to change simulation speed.
 */
message SetSpeedRequest {
  float speed_factor = 1; // 1.0 for real-time, 0.0 for paused
}
message SetSpeedResponse {}

/**
 * Request to enable or disable a node's radio.
 */
message SetNodeStateRequest {
  uint32 node_id = 1;
  bool enabled = 2;
}
message SetNodeStateResponse {}

/**
 * Request to move a node in the simulation space.
 */
message SetNodePositionRequest {
  uint32 node_id = 1;
  float x = 2;
  float y = 3;
}
message SetNodePositionResponse {}

/**
 * Request to create a new node at a given position.
 */
message CreateNodeRequest {
  float x = 1;
  float y = 2;
}

message CreateNodeResponse {
  uint32 node_id = 1;
}

/**
 * Request to form a new Thread network on the specified node.
 */
message FormNetworkRequest {
  uint32 node_id = 1;
}

message FormNetworkResponse {}

/**
 * Thread device types for joining.
 */
enum JoinMode {
  JOIN_MODE_FTD = 0;
  JOIN_MODE_MED = 1;
  JOIN_MODE_SED = 2;
  JOIN_MODE_FED = 3;
}

/**
 * Request for a node to join an existing network.
 */
message JoinNetworkRequest {
  uint32 node_id = 1;
  uint32 target_node_id = 2;
  JoinMode mode = 3; 
}

message JoinNetworkResponse {}

/**
 * Nexus simulation control and monitoring service.
 */
service NexusService {
  /**
   * Streams simulation events to the client.
   */
  rpc StreamEvents(StreamRequest) returns (stream SimulationEvent);

  /**
   * Resets the simulation to the initial state.
   */
  rpc Reset(ResetRequest) returns (ResetResponse);

  /**
   * Sets the simulation speed factor.
   */
  rpc SetSpeed(SetSpeedRequest) returns (SetSpeedResponse);

  /**
   * Enables or disables a node.
   */
  rpc SetNodeState(SetNodeStateRequest) returns (SetNodeStateResponse);

  /**
   * Moves a node to a new position.
   */
  rpc SetNodePosition(SetNodePositionRequest) returns (SetNodePositionResponse);

  /**
   * Adds a new node to the simulation.
   */
  rpc CreateNode(CreateNodeRequest) returns (CreateNodeResponse);

  /**
   * Forms a network on a node.
   */
  rpc FormNetwork(FormNetworkRequest) returns (FormNetworkResponse);

  /**
   * Joins a node to a network.
   */
  rpc JoinNetwork(JoinNetworkRequest) returns (JoinNetworkResponse);

  /**
   * Retrieves the radio model parameters.
   */
  rpc GetRadioParameters(GetRadioParametersRequest) returns (GetRadioParametersResponse);
}

message GetRadioParametersRequest {}

message GetRadioParametersResponse {
  float path_loss_constant = 1;
  float path_loss_exponent = 2;
  float radio_sensitivity = 3;
  int32 mle_link_request_margin_min = 4;
}

message StreamRequest {
  bool live = 1; // Reserved for future use
}
