package org.metaborg.runtime.task.primitives;

import org.metaborg.runtime.task.ITaskEngine;
import org.metaborg.runtime.task.Task;
import org.metaborg.runtime.task.TaskInsertion;
import org.metaborg.runtime.task.TaskManager;
import org.metaborg.runtime.task.util.InvokeStrategy;
import org.metaborg.runtime.task.util.ListBuilder;
import org.spoofax.interpreter.core.IContext;
import org.spoofax.interpreter.core.InterpreterException;
import org.spoofax.interpreter.library.AbstractPrimitive;
import org.spoofax.interpreter.stratego.Strategy;
import org.spoofax.interpreter.terms.IStrategoList;
import org.spoofax.interpreter.terms.IStrategoTerm;
import org.spoofax.interpreter.terms.ITermFactory;

import fj.P2;

public class task_api_result_combinations_2_1 extends AbstractPrimitive {
	public static task_api_result_combinations_2_1 instance = new task_api_result_combinations_2_1();

	public task_api_result_combinations_2_1() {
		super("task_api_result_combinations", 2, 1);
	}

	@Override
	public boolean call(IContext env, Strategy[] svars, IStrategoTerm[] tvars)
			throws InterpreterException {
		final ITermFactory factory = env.getFactory();
		final ITaskEngine taskEngine = TaskManager.getInstance().getCurrent();
		final IStrategoTerm term = tvars[0];
		final Strategy collect = svars[0];
		final Strategy insert = svars[1];
		final IStrategoTerm resultIDs = InvokeStrategy.invoke(env, collect,
				term);

		// HACK: produce dependencies if any of the results has not been solved
		// yet.
		IStrategoList dependencies = factory.makeList();
		for (IStrategoTerm taskID : resultIDs) {
			final Task task = taskEngine.getTask(taskID);
			if (!task.solved())
				dependencies = factory.makeListCons(taskID, dependencies);
		}
		if (!dependencies.isEmpty()) {
			env.setCurrent(factory.makeAppl(
					factory.makeConstructor("Dependency", 1), dependencies));
			return true;
		}

		final P2<? extends Iterable<IStrategoTerm>, Boolean> combinations = TaskInsertion
				.insertResultCombinations(taskEngine, env, collect, insert,
						term, resultIDs);
		if (combinations == null)
			return false;
		env.setCurrent(ListBuilder.makeList(factory, combinations._1()));
		return true;
	}
}

@@ -90,47 +90,8 @@
 ne;%0A
-import org.metaborg.runtime.task.Task;%0A
 impo
@@ -1024,20 +1024,17 @@
 %5D tvars)
-%0A%09%09%09
+ 
 throws I
@@ -1289,16 +1289,17 @@
 ars%5B1%5D;%0A
+%0A
 %09%09final 
@@ -1363,370 +1363,455 @@
 ect,
-%0A%09%09%09%09
+ 
 term);%0A
-%0A
 %09%09
-// HACK: produce dependencies if any of the results has not been solved%0A%09%09// yet.%0A%09%09IStrategoList dependencies = factory.makeList();%0A%09%09for (IStrategoTerm taskID : resultIDs) %7B%0A%09%09%09final Task task = taskEngine.getTask(taskID);%0A%09
+final P2%3C? extends Iterable%3CIStrategoTerm%3E, Boolean%3E result =%0A%09%09%09TaskInsertion.insertResultCombinations(taskEngine, env, collect, insert, term, resultIDs);%0A%09%09if(result._1() == null)%0A%09%09%09return false; // No combinations could be constructed because a dependency failed or had no results.%0A%09%09final IStrategoList resultList = ListBuilder.makeList(factory, result._1());%0A%0A
 %09%09if
- (!task.solved
+(result._2
 ())
+ %7B
 %0A%09%09%09
-%09dependencies = factory.makeListCons(
+// Results are 
 task
+ 
 ID
-, dependencies);%0A%09%09%7D%0A%09%09if (!dependencies.isEmpty()) %7B
+s of dependencies instead.
 %0A%09%09%09
@@ -1842,22 +1842,16 @@
 akeAppl(
-%0A%09%09%09%09%09
 factory.
@@ -1888,329 +1888,68 @@
 1), 
-dependencies));%0A%09%09%09return true;%0A%09%09%7D%0A%0A%09%09final P2%3C? extends Iterable%3CIStrategoTerm%3E, Boolean%3E combinations = TaskInsertion%0A%09%09%09%09.insertResultCombinations(taskEngine, env, collect, insert,%0A%09%09%09%09%09%09term, resultIDs);%0A%09%09if (combinations == null)%0A%09%09%09return false;%0A%09%09env.setCurrent(ListBuilder.makeList(factory, combinations._1()));
+resultList));%0A%09%09%7D else %7B%0A%09%09%09env.setCurrent(resultList);%0A%09%09%7D%0A
 %0A%09%09r

Revert "adopt insertion strategy to FJ pairs"