use crate::config::ProjectConfig;
use crate::detectors::DetectorTrait;
use crate::models::{DetectionSource, Service};
use crate::utils::ServiceSignatures;
use anyhow::Result;
use async_trait::async_trait;
use std::path::Path;
use sysinfo::System;
use tracing::debug;
pub struct ProcessDetector;
impl ProcessDetector {
pub fn new() -> Self {
Self
}
}
#[async_trait]
impl DetectorTrait for ProcessDetector {
fn name(&self) -> &str {
"ProcessDetector"
}
fn priority(&self) -> i32 {
20
}
async fn detect(&self, project_path: &Path, _config: Option<&ProjectConfig>) -> Result<Vec<Service>> {
let mut services = Vec::new();
let mut sys = System::new_all();
sys.refresh_all();
for (pid, process) in sys.processes() {
let process_name = process.name();
let cmd = process.cmd();
if let Some(signature) = ServiceSignatures::find_by_process(process_name) {
let mut service = Service::new(
signature.name.to_string(),
signature.service_type.clone(),
"localhost".to_string(),
signature.port,
DetectionSource::ProcessScan,
project_path.to_string_lossy().to_string(),
);
service.pid = Some(pid.as_u32());
service.process_name = Some(process_name.to_string());
service.command_line = Some(cmd.join(" "));
service.tags.push("auto-detected".to_string());
services.push(service);
debug!("Detected {} via process (PID: {})", signature.name, pid);
}
}
Ok(services)
}
}