use crate::analysis::DependencyGraph;
use crate::model::Issue;
use petgraph::algo::tarjan_scc;
pub fn detect_circular_dependencies(graph: &DependencyGraph) -> Vec<Issue> {
let mut issues = Vec::new();
let sccs = tarjan_scc(graph.graph());
for scc in sccs {
if scc.len() > 1 {
let cycle: Vec<_> = scc
.iter()
.filter_map(|idx| graph.graph().node_weight(*idx).cloned())
.collect();
if !cycle.is_empty() {
issues.push(Issue::circular_dependency(cycle));
}
} else if scc.len() == 1 {
let idx = scc[0];
if graph
.graph()
.neighbors_directed(idx, petgraph::Direction::Outgoing)
.any(|n| n == idx)
{
if let Some(path) = graph.graph().node_weight(idx) {
issues.push(Issue::circular_dependency(vec![path.clone()]));
}
}
}
}
issues
}