package build.pluto.test.build;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.sugarj.common.Log;

import build.pluto.builder.BuildCycleException;
import build.pluto.builder.BuildManager;
import build.pluto.builder.BuildRequest;
import build.pluto.builder.Builder;
import build.pluto.builder.factory.BuilderFactory;
import build.pluto.dependency.BuildRequirement;
import build.pluto.output.Output;
import build.pluto.util.IReporting.BuildReason;
import build.pluto.util.LogReporting;

public class TrackingBuildManager extends BuildManager {

	private List<Serializable> requiredInputs = new ArrayList<>();
	private List<Serializable> executedInputs = new ArrayList<>();
	private List<Serializable> successfullyExecutedInputs = new ArrayList<>();

	public TrackingBuildManager() {
		super(new LogReporting());
	}

	public <In extends Serializable, Out extends Output, B extends Builder<In, Out>, F extends BuilderFactory<In, Out, B>> BuildRequirement<Out> 
	    require(F factory, In input) throws IOException {
    return require(factory, input, true);
  }

	public <In extends Serializable, Out extends Output, B extends Builder<In, Out>, F extends BuilderFactory<In, Out, B>> BuildRequirement<Out> 
	    require(F factory, In input, boolean needBuildResult) throws IOException {
		requiredInputs.add(input);
		return super.require(new BuildRequest<>(factory, input), needBuildResult);
	}

	@Override
	public <In extends Serializable, Out extends Output, B extends Builder<In, Out>, F extends BuilderFactory<In, Out, B>> BuildRequirement<Out> 
	    require(BuildRequest<In, Out, B, F> buildReq, boolean needBuildResult) throws IOException {
		requiredInputs.add(buildReq.input);
		Log.log.log("Require " + buildReq, Log.DETAIL);
		return super.require(buildReq, needBuildResult);
	}

	 // @formatter:off
	@Override
  protected 
    <In extends Serializable,
     Out extends Output,
     B extends Builder<In, Out>,
     F extends BuilderFactory<In, Out, B>>
  // @formatter:on
	BuildRequirement<Out> executeBuilder(Builder<In, Out> builder, File dep, BuildRequest<In, Out, B, F> buildReq, Set<BuildReason> reasons) throws IOException {
		executedInputs.add(buildReq.input);
		try {
		  BuildRequirement<Out> result = super.executeBuilder(builder, dep, buildReq, reasons);
  		successfullyExecutedInputs.add(buildReq.input);
  		return result;
		} catch (BuildCycleException e) {
		//  if (e.getCycleState() == CycleState.RESOLVED)
		 //   successfullyExecutedInputs.add(buildReq.input);
		  throw e;
		}
	}

	public List<Serializable> getRequiredInputs() {
		return requiredInputs;
	}

	public List<Serializable> getExecutedInputs() {
		return executedInputs;
	}

	public List<Serializable> getSuccessfullyExecutedInputs() {
		return successfullyExecutedInputs;
	}

}

@@ -856,16 +856,90 @@
 ist%3C%3E();
+%0A%09private List%3CBuilderFactory%3C?, ?, ?%3E%3E executedTools = new ArrayList%3C%3E();
 %0A%0A%09publi
@@ -2323,16 +2323,56 @@
 ption %7B%0A
+%09  executedTools.add(buildReq.factory);%0A
 %09%09execut
@@ -2993,10 +2993,99 @@
 ts;%0A%09%7D%0A%0A
+%09public List%3CBuilderFactory%3C?, ?, ?%3E%3E getExecutedTools() %7B%0A    return executedTools;%0A  %7D%0A
 %7D%0A

improve tracking BM for testing