package jetbrains.mps.build.workflow.generator.util;
/*Generated by MPS */
import java.util.List;
import org.jetbrains.mps.openapi.model.SNode;
import java.util.Map;
import java.util.HashMap;
import jetbrains.mps.generator.template.TemplateQueryContext;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.util.GraphUtil;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;
public class SubTaskOrderHelper {
private final List<SNode> list;
private final Map<SNode, SubTaskOrderHelper.SubTask> map = new HashMap<SNode, SubTaskOrderHelper.SubTask>();
private final TemplateQueryContext genContext;
public SubTaskOrderHelper(List<SNode> list, TemplateQueryContext genContext) {
this.list = list;
this.genContext = genContext;
}
public void sort() {
int count = 0;
SubTaskOrderHelper.SubTask[] subtasks = new SubTaskOrderHelper.SubTask[ListSequence.fromList(list).count()];
for (SNode st : list) {
SubTaskOrderHelper.SubTask wrapper = new SubTaskOrderHelper.SubTask(st, count);
map.put(st, wrapper);
subtasks[count++] = wrapper;
}
for (SubTaskOrderHelper.SubTask st : subtasks) {
for (SNode dep : SLinkOperations.getChildren(st.getTask(), MetaAdapterFactory.getContainmentLink(0x698a8d22a10447a0L, 0xba8d10e3ec237f13L, 0x2670d5989d5a6275L, 0x2670d5989d5b4a01L, "after"))) {
SubTaskOrderHelper.SubTask afterTask = map.get(SLinkOperations.getTarget(dep, MetaAdapterFactory.getReferenceLink(0x698a8d22a10447a0L, 0xba8d10e3ec237f13L, 0x2670d5989d5b49b8L, 0x2670d5989d5b49b9L, "target")));
if (afterTask == null) {
genContext.showErrorMessage(dep, "dependency on non-existing subtask");
continue;
}
st.targets.add(afterTask.getIndex());
}
for (SNode dep : SLinkOperations.getChildren(st.getTask(), MetaAdapterFactory.getContainmentLink(0x698a8d22a10447a0L, 0xba8d10e3ec237f13L, 0x2670d5989d5a6275L, 0x36fb0dc9fd36bb1bL, "before"))) {
SubTaskOrderHelper.SubTask beforeTask = map.get(SLinkOperations.getTarget(dep, MetaAdapterFactory.getReferenceLink(0x698a8d22a10447a0L, 0xba8d10e3ec237f13L, 0x2670d5989d5b49b8L, 0x2670d5989d5b49b9L, "target")));
if (beforeTask == null) {
genContext.showErrorMessage(dep, "dependency on non-existing subtask");
continue;
}
beforeTask.targets.add(st.getIndex());
}
}
int[][] graph = new int[count][];
for (SubTaskOrderHelper.SubTask st : subtasks) {
graph[st.getIndex()] = st.getTargets();
}
int[][] partitions = GraphUtil.tarjan(graph);
ListSequence.fromList(list).clear();
for (int[] cycle : partitions) {
if (cycle.length > 1) {
StringBuilder sb = new StringBuilder();
sb.append("subtasks cycle detected: ");
for (int i = 0; i < 5 && i < cycle.length; i++) {
if (i > 0) {
sb.append(", ");
}
sb.append(SPropertyOperations.getString(subtasks[cycle[i]].getTask(), MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name")));
}
if (cycle.length > 5) {
sb.append(" ...");
}
genContext.showErrorMessage(subtasks[cycle[0]].getTask(), sb.toString());
continue;
}
ListSequence.fromList(list).addElement(subtasks[cycle[0]].getTask());
}
}
private class SubTask {
private final int index;
private final SNode task;
public final Set<Integer> targets = new HashSet<Integer>();
public SubTask(SNode task, int index) {
this.task = task;
this.index = index;
}
public int[] getTargets() {
targets.remove(index);
int[] arr = new int[targets.size()];
if (targets.isEmpty()) {
return arr;
}
int i = 0;
for (Integer val : targets) {
arr[i++] = val;
}
assert i == targets.size();
if (arr.length > 1) {
Arrays.sort(arr);
}
return arr;
}
public SNode getTask() {
return task;
}
public int getIndex() {
return index;
}
}
}