#[allow(clippy::too_many_arguments)]
pub async fn handle_analyze_satd(
path: PathBuf,
format: SatdOutputFormat,
severity: Option<SatdSeverity>,
critical_only: bool,
include_tests: bool,
evolution: bool,
days: u32,
metrics: bool,
output: Option<PathBuf>,
) -> Result<()> {
use crate::services::satd_detector::SATDDetector;
eprintln!("🔍 Analyzing Self-Admitted Technical Debt (SATD)...");
let detector = SATDDetector::new();
let satd_items = analyze_satd_items(&detector, &path, include_tests).await?;
let filtered_items = apply_satd_filters(satd_items, severity, critical_only);
let output_content = generate_satd_output(format, &filtered_items, metrics, evolution, days);
write_satd_output(output, &output_content).await?;
if metrics {
print_satd_metrics(&filtered_items);
}
Ok(())
}
async fn analyze_satd_items(
detector: &crate::services::satd_detector::SATDDetector,
path: &Path,
include_tests: bool,
) -> Result<Vec<crate::services::satd_detector::TechnicalDebt>> {
if include_tests {
detector
.analyze_directory_with_tests(path, true)
.await
.map_err(Into::into)
} else {
detector.analyze_directory(path).await.map_err(Into::into)
}
}
pub fn apply_satd_filters(
mut satd_items: Vec<crate::services::satd_detector::TechnicalDebt>,
severity: Option<SatdSeverity>,
critical_only: bool,
) -> Vec<crate::services::satd_detector::TechnicalDebt> {
if let Some(min_severity) = severity {
let min_sev = match min_severity {
SatdSeverity::Critical => crate::services::satd_detector::Severity::Critical,
SatdSeverity::High => crate::services::satd_detector::Severity::High,
SatdSeverity::Medium => crate::services::satd_detector::Severity::Medium,
SatdSeverity::Low => crate::services::satd_detector::Severity::Low,
};
satd_items.retain(|item| item.severity as u8 >= min_sev as u8);
}
if critical_only {
satd_items.retain(|item| {
matches!(
item.severity,
crate::services::satd_detector::Severity::Critical
| crate::services::satd_detector::Severity::High
)
});
}
satd_items
}
fn generate_satd_output(
format: SatdOutputFormat,
filtered_items: &[crate::services::satd_detector::TechnicalDebt],
metrics: bool,
evolution: bool,
days: u32,
) -> String {
match format {
SatdOutputFormat::Summary => format_satd_summary(filtered_items),
SatdOutputFormat::Json => format_satd_json(filtered_items, metrics, evolution),
SatdOutputFormat::Sarif => format_satd_sarif(filtered_items),
SatdOutputFormat::Markdown => format_satd_markdown(filtered_items, evolution, days),
}
}
async fn write_satd_output(output: Option<PathBuf>, content: &str) -> Result<()> {
if let Some(output_path) = output {
tokio::fs::write(&output_path, content).await?;
eprintln!("✅ SATD analysis written to: {}", output_path.display());
} else {
println!("{content}");
}
Ok(())
}
#[allow(clippy::too_many_arguments)]
pub async fn handle_analyze_dag(
dag_type: DagType,
project_path: PathBuf,
output: Option<PathBuf>,
max_depth: Option<usize>,
filter_external: bool,
show_complexity: bool,
include_duplicates: bool,
include_dead_code: bool,
enhanced: bool,
) -> Result<()> {
eprintln!("🔍 Analyzing Directed Acyclic Graph (DAG)...");
eprintln!("📊 DAG Type: {dag_type:?}");
eprintln!("📁 Project: {}", project_path.display());
let mut output_content = String::new();
output_content.push_str(&format!("# {dag_type:?} DAG Analysis\n\n"));
output_content.push_str(&format!("Project: {}\n", project_path.display()));
if let Some(depth) = max_depth {
output_content.push_str(&format!("Max depth: {depth}\n"));
}
output_content.push_str(&format!("Filter external: {filter_external}\n"));
output_content.push_str(&format!("Show complexity: {show_complexity}\n"));
output_content.push_str(&format!("Include duplicates: {include_duplicates}\n"));
output_content.push_str(&format!("Include dead code: {include_dead_code}\n"));
output_content.push_str(&format!("Enhanced mode: {enhanced}\n"));
output_content.push_str("\n## Analysis Results\n");
output_content.push_str(
"DAG analysis functionality will be implemented with proper AST-based analysis.\n",
);
if let Some(output_path) = output {
tokio::fs::write(&output_path, &output_content).await?;
eprintln!("✅ DAG analysis written to: {}", output_path.display());
} else {
println!("{output_content}");
}
Ok(())
}