darpan 0.2.5

Linux developer service monitoring utility with auto-detection, real-time health checks, and interactive TUI for databases, APIs, Docker containers, and more
Documentation
use crate::config::{ConfigLoader, ProjectConfig, UserConfig};
use crate::core::{
    detector_registry::DetectorRegistry,
    pack_integration::PackIntegration,
    registry::ServiceRegistry,
    registry_builder::RegistryBuilder,
};
use crate::health::HealthCheckerRegistry;
use crate::logs::log_registry::LogStreamerRegistry;
use crate::packs::schema::ServicePack;
use anyhow::Result;
use std::path::PathBuf;
use tracing::info;

pub struct CoreEngine {
    project_path: PathBuf,
    registry: ServiceRegistry,
    user_config: UserConfig,
    project_config: Option<ProjectConfig>,
    detector_registry: DetectorRegistry,
    health_registry: HealthCheckerRegistry,
    log_registry: LogStreamerRegistry,
    service_packs: Vec<ServicePack>,
}

impl CoreEngine {
    pub fn new(project_path: PathBuf) -> Result<Self> {
        info!("Initializing Darpan for project: {:?}", project_path);
        
        let user_config = ConfigLoader::load_user_config()?;
        let project_config = ConfigLoader::load_project_config(&project_path)?;
        
        // Build registries with built-in components
        let mut detector_registry = RegistryBuilder::build_detector_registry(
            &user_config.detection.enabled_detectors,
            user_config.detection.port_range,
        );
        
        let mut health_registry = RegistryBuilder::build_health_registry(
            std::time::Duration::from_secs(user_config.health_checks.timeout),
        );
        
        let mut log_registry = RegistryBuilder::build_log_registry();
        
        // Load and integrate service packs
        let service_packs = PackIntegration::integrate_packs(
            &project_path,
            &mut detector_registry,
            &mut health_registry,
            &mut log_registry,
        )?;
        
        Ok(Self {
            project_path,
            registry: ServiceRegistry::new(),
            user_config,
            project_config,
            detector_registry,
            health_registry,
            log_registry,
            service_packs,
        })
    }

    pub async fn detect_services(&mut self) -> Result<()> {
        info!("Starting service detection");
        self.registry.clear();
        
        // Use detector registry to detect services
        let mut services = self
            .detector_registry
            .detect(&self.project_path, self.project_config.as_ref())
            .await?;
        
        // Apply pack defaults to detected services
        for service in &mut services {
            PackIntegration::apply_pack_defaults(service, &self.service_packs);
        }
        
        for service in services {
            self.registry.merge_or_update(service);
        }
        
        info!("Detection complete. Found {} services", self.registry.count());
        Ok(())
    }

    pub async fn check_health(&mut self) -> Result<()> {
        info!("Starting health checks");
        
        for service in self.registry.all_services_mut() {
            let health_result = self.health_registry.check(service).await;
            service.health_status = Some(health_result);
        }
        
        info!("Health checks complete");
        Ok(())
    }

    /// Get mutable access to detector registry for extension
    pub fn detector_registry_mut(&mut self) -> &mut DetectorRegistry {
        &mut self.detector_registry
    }

    /// Get mutable access to health registry for extension
    pub fn health_registry_mut(&mut self) -> &mut HealthCheckerRegistry {
        &mut self.health_registry
    }

    /// Get mutable access to log registry for extension
    pub fn log_registry_mut(&mut self) -> &mut LogStreamerRegistry {
        &mut self.log_registry
    }

    /// Get loaded service packs
    pub fn service_packs(&self) -> &[ServicePack] {
        &self.service_packs
    }

    pub async fn refresh(&mut self) -> Result<()> {
        self.detect_services().await?;
        self.check_health().await?;
        Ok(())
    }

    pub fn get_registry(&self) -> &ServiceRegistry {
        &self.registry
    }

    pub fn get_registry_mut(&mut self) -> &mut ServiceRegistry {
        &mut self.registry
    }

    pub fn project_path(&self) -> &PathBuf {
        &self.project_path
    }

    pub fn user_config(&self) -> &UserConfig {
        &self.user_config
    }

    pub fn project_config(&self) -> Option<&ProjectConfig> {
        self.project_config.as_ref()
    }
}