righvalor 0.1.0

RighValor: AI Infrastructure and Applications Framework for the Far Edge
use std::path::PathBuf;

use righ_dm_rs::RighIpv4Addr;
use tokio::{
    io::{AsyncReadExt, AsyncWriteExt},
    net::UnixStream,
};

use crate::{
    types::ValorID,
    uds::{UdsRegistrationResponse, UdsWorkerRegistration},
};

/// # UDS Client Tool
///
/// UDS client tool for development and testing.
/// Used to register workers with master via UDS.
/// In production, this will be replaced by external software.
pub struct UdsClientTool;

impl UdsClientTool {
    /// Register a worker with master via UDS
    /// This sends worker registration request to master's UDS server
    pub async fn register_worker(
        worker_id: &ValorID,
        ipv4_addr: RighIpv4Addr,
        uds_path: &PathBuf,
    ) -> anyhow::Result<UdsRegistrationResponse> {
        tracing::info!(
            "UDS Client Tool: Registering worker {}@{}",
            worker_id,
            ipv4_addr
        );

        // Create registration request
        let registration = UdsWorkerRegistration {
            worker_id: worker_id.clone(),
            ipv4_addr,
        };

        tracing::info!(
            "UDS Client Tool: Sending worker registration to master's UDS server: {:?}",
            registration
        );

        // Connect to master's UDS server
        let mut stream = UnixStream::connect(uds_path).await?;

        // Serialize and send registration request
        let registration_bytes = serde_json::to_vec(&registration)?;
        stream.write_all(&registration_bytes).await?;

        // Close write side to signal end of data
        stream.shutdown().await?;

        tracing::info!(
            "UDS Client Tool: Worker registration request sent to master for worker {}",
            worker_id
        );

        // Read response from master
        let mut buffer = Vec::new();
        let mut chunk = [0u8; 1024];

        loop {
            match stream.read(&mut chunk).await {
                Ok(n) => {
                    if n == 0 {
                        break; // EOF
                    }
                    buffer.extend_from_slice(&chunk[..n]);
                }
                Err(e) => {
                    tracing::error!("Error reading response from UDS stream: {}", e);
                    break;
                }
            }
        }

        // Deserialize response
        match serde_json::from_slice::<UdsRegistrationResponse>(&buffer) {
            Ok(response) => {
                tracing::info!(
                    "UDS Client Tool: Received response from master for worker {}: {:?}",
                    worker_id,
                    response
                );
                Ok(response)
            }
            Err(e) => {
                tracing::error!("Failed to deserialize response: {}", e);
                Err(anyhow::anyhow!("Failed to deserialize response: {}", e))
            }
        }
    }
}