use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; // Simple RouterManager that just tracks status without complex state management pub struct RouterManager { is_running: Arc, } impl RouterManager { pub async fn new( config: &crate::cfg::config::Config, ) -> Result> { if !config.router.integrated_router { return Ok(Self { is_running: Arc::new(AtomicBool::new(false)), }); } // Initialize router synchronously to avoid Send issues Self::init_router(config).await?; let manager = Self { is_running: Arc::new(AtomicBool::new(true)), }; // Give the router some time to initialize tokio::time::sleep(std::time::Duration::from_secs(2)).await; Ok(manager) } async fn init_router( config: &crate::cfg::config::Config, ) -> Result<(), Box> { use crate::router::router::{Emissary, EmissaryConfig, RouterUtils}; use std::path::Path; let router_config = &config.router; let mut router = Emissary::new(EmissaryConfig { storage: Some(std::path::PathBuf::from(&router_config.storage_path)), auto_update: Some(router_config.auto_update), http_proxy_port: Some(router_config.http_proxy_port), socks_proxy_port: Some(router_config.socks_proxy_port), }); router.config().await?; let storage_path = Path::new(&router_config.storage_path); if !storage_path.exists() { std::fs::create_dir_all(storage_path)?; } // Check if storage directory is empty let should_reseed = match std::fs::read_dir(storage_path) { Ok(mut entries) => entries.next().is_none(), Err(_) => true, // if we can't read, reseed anyway }; if should_reseed { println!("Router storage is empty, performing initial reseed..."); router.reseed().await?; } let router_instance = router.start().await?; // Store the router instance in the global static variable *super::router::ROUTER.lock().await = Some(router_instance); println!("Router service successfully initialized and stored globally"); Ok(()) } /// Starts the integrated router if it is not currently running. /// Note: The router is typically started automatically when the RouterManager is created, /// so calling this method usually just prints a message indicating that the router /// starts automatically. /// /// # Returns /// /// * `Ok(())` always returns OK as this is a compatibility method pub async fn start(&self) -> Result<(), Box> { if !self.is_running.load(Ordering::SeqCst) { println!("Router start functionality not implemented for this mode"); // We can't really control the router lifecycle since it's managed globally } Ok(()) } /// Restarts the integrated router if it is currently running. /// This stops the current router instance and starts a new one. /// /// # Returns /// /// * `Ok(())` when the restart is initiated /// * `Err(Box)` if the restart failed pub async fn restart(&self) -> Result<(), Box> { println!("Restarting router..."); // Clear the global router instance *super::router::ROUTER.lock().await = None; // Get config again (this is not ideal but needed for restart) let config = crate::cfg::config::Config::parse() .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; Self::init_router(&config).await?; println!("Router restarted successfully"); Ok(()) } /// Stops the integrated router if it is currently running. /// This clears the global router instance. pub async fn stop(&self) -> Result<(), Box> { if self.is_running.load(Ordering::SeqCst) { println!("Stopping router..."); // Clear the global router instance *super::router::ROUTER.lock().await = None; self.is_running.store(false, Ordering::SeqCst); println!("Router stopped"); } Ok(()) } pub fn is_running(&self) -> bool { self.is_running.load(Ordering::SeqCst) } } /* impl Drop for RouterManager { fn drop(&mut self) { //todooo } } */