use crate::config::{ConfigLoader, ProjectConfig, UserConfig};
use crate::core::registry::ServiceRegistry;
use crate::detectors::{ConfigDetector, DetectorTrait, DockerDetector, PortDetector, ProcessDetector};
use crate::health::HealthChecker;
use anyhow::Result;
use std::path::PathBuf;
use tracing::{debug, info};
pub struct CoreEngine {
project_path: PathBuf,
registry: ServiceRegistry,
user_config: UserConfig,
project_config: Option<ProjectConfig>,
detectors: Vec<Box<dyn DetectorTrait>>,
health_checker: HealthChecker,
}
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)?;
let mut detectors: Vec<Box<dyn DetectorTrait>> = Vec::new();
if user_config.detection.enabled_detectors.contains(&"config".to_string()) {
detectors.push(Box::new(ConfigDetector::new()));
}
if user_config.detection.enabled_detectors.contains(&"port".to_string()) {
detectors.push(Box::new(PortDetector::new(
user_config.detection.port_range.0,
user_config.detection.port_range.1,
)));
}
if user_config.detection.enabled_detectors.contains(&"process".to_string()) {
detectors.push(Box::new(ProcessDetector::new()));
}
if user_config.detection.enabled_detectors.contains(&"docker".to_string()) {
detectors.push(Box::new(DockerDetector::new()));
}
let health_checker = HealthChecker::new(
std::time::Duration::from_secs(user_config.health_checks.timeout),
user_config.health_checks.retry_count,
);
Ok(Self {
project_path,
registry: ServiceRegistry::new(),
user_config,
project_config,
detectors,
health_checker,
})
}
pub async fn detect_services(&mut self) -> Result<()> {
info!("Starting service detection");
self.registry.clear();
for detector in &self.detectors {
debug!("Running detector: {}", detector.name());
let services = detector.detect(&self.project_path, self.project_config.as_ref()).await?;
debug!("Detector {} found {} services", detector.name(), services.len());
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_checker.check(service).await;
service.health_status = Some(health_result);
}
info!("Health checks complete");
Ok(())
}
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()
}
}