package fr.monlouyan.bakefile; import java.util.*; public class DependencyResolver { private boolean debug; private Map ruleMap; public DependencyResolver(boolean debug) { this.debug = debug; } public List resolve(List allRules, List requestedRules) { List rulesToBuild = new ArrayList<>(); ruleMap = new HashMap<>(); Set builtRules = new HashSet<>(); // Éviter d'ajouter des règles déjà vérifiées for (Rule rule : allRules) { ruleMap.put(rule.getName(), rule); } Set visited = new HashSet<>(); Set stack = new HashSet<>(); for (String ruleName : requestedRules.isEmpty() ? ruleMap.keySet() : requestedRules) { if (ruleMap.containsKey(ruleName)) { detectCycle(ruleName, visited, stack); collectDependencies(ruleName, rulesToBuild, builtRules); } else if (debug) { System.out.println("Warning: Rule '" + ruleName + "' not found."); } } return rulesToBuild; } /** * Détection des cycles avec DFS */ private void detectCycle(String ruleName, Set visited, Set stack) { if (stack.contains(ruleName)) { throw new RuntimeException("Dependency cycle detected involving rule: " + ruleName); } if (!visited.contains(ruleName)) { visited.add(ruleName); stack.add(ruleName); Rule rule = ruleMap.get(ruleName); if (rule != null) { for (String dependency : rule.getDependencies()) { if (ruleMap.containsKey(dependency)) { detectCycle(dependency, visited, stack); } } } stack.remove(ruleName); } } /** * Collecte récursive des règles à construire en évitant les doublons */ private void collectDependencies(String ruleName, List rulesToBuild, Set builtRules) { if (builtRules.contains(ruleName)) { return; // Évite d'ajouter une règle plusieurs fois } Rule rule = ruleMap.get(ruleName); if (rule != null) { for (String dependency : rule.getDependencies()) { if (ruleMap.containsKey(dependency)) { collectDependencies(dependency, rulesToBuild, builtRules); } } rulesToBuild.add(rule); builtRules.add(ruleName); } } }