use super::service::TypeService;
use crate::agent::AgentCoordinator;
use crate::core::SharedUniverse;
use std::net::SocketAddr;
use std::sync::Arc;
use tracing::info;
#[derive(Debug, Clone)]
pub struct ApiConfig {
pub bind_address: SocketAddr,
pub max_concurrent_streams: usize,
pub enable_reflection: bool,
}
impl Default for ApiConfig {
fn default() -> Self {
Self {
bind_address: "[::1]:50051".parse().unwrap(),
max_concurrent_streams: 100,
enable_reflection: true,
}
}
}
pub struct ApiServer {
config: ApiConfig,
service: TypeService,
}
impl ApiServer {
pub fn new(config: ApiConfig, universe: SharedUniverse) -> Self {
let coordinator = Arc::new(AgentCoordinator::new(universe.clone()));
let service = TypeService::new(universe, coordinator);
Self { config, service }
}
pub async fn start(&self) -> Result<(), ApiError> {
info!("Starting API server on {}", self.config.bind_address);
info!(
"gRPC server placeholder - would start on {}",
self.config.bind_address
);
Ok(())
}
pub async fn health_check(&self) -> HealthStatus {
HealthStatus {
healthy: true,
active_sessions: 0, uptime_seconds: 0,
}
}
}
#[derive(Debug, Clone)]
pub struct HealthStatus {
pub healthy: bool,
pub active_sessions: usize,
pub uptime_seconds: u64,
}
#[derive(Debug)]
pub enum ApiError {
Transport(tonic::transport::Error),
Bind(std::io::Error),
}
impl std::fmt::Display for ApiError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Transport(e) => write!(f, "Transport error: {}", e),
Self::Bind(e) => write!(f, "Bind error: {}", e),
}
}
}
impl std::error::Error for ApiError {}
pub struct RestServer {
bind_address: SocketAddr,
service: TypeService,
}
impl RestServer {
pub fn new(bind_address: SocketAddr, service: TypeService) -> Self {
Self {
bind_address,
service,
}
}
pub async fn start(&self) -> Result<(), ApiError> {
info!("REST server would start on {}", self.bind_address);
Ok(())
}
}
pub struct WebSocketServer {
bind_address: SocketAddr,
service: TypeService,
}
impl WebSocketServer {
pub fn new(bind_address: SocketAddr, service: TypeService) -> Self {
Self {
bind_address,
service,
}
}
pub async fn start(&self) -> Result<(), ApiError> {
info!("WebSocket server would start on {}", self.bind_address);
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::TypeUniverse;
use std::sync::Arc;
#[test]
fn test_server_creation() {
let universe = Arc::new(TypeUniverse::new());
let config = ApiConfig::default();
let _server = ApiServer::new(config, universe);
}
}