package interactivefeaturelocator.model;

//import interactivefeaturelocator.layout.CallTreeLayout;
import interactivefeaturelocator.test.Test;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.JavaModelException;
import org.ntlab.trace.MethodExecution;
import org.ntlab.trace.Trace;

public class DerivationUnit {
	private Trace plusTrace = null;
	private Trace minusTrace = null;
	private ArrayList<Mark> marks = new ArrayList<>();
	private ArrayList<DerivationSession> sessions = null;
	private DerivationSession activeSession = null;
//	private CallTreeLayout callTreeLayout = null;
	private DerivationResults result = new DerivationResults();
	
	public DerivationUnit(Pattern pattern) {
		this.plusTrace = new Trace(pattern.getPlusTraceFilePath());
		this.minusTrace = new Trace(pattern.getMinusTraceFilePath());
		this.marks = readMarkFile(pattern.getMarkFilePath());
//		this.callTreeLayout = new CallTreeLayout();
	}

	public Trace getPlusTrace() {
		return plusTrace;
	}
	public Trace getMinusTrace() {
		return minusTrace;
	}

	public DerivationSession getActiveSession() {
		return activeSession;
	}
	
	public DerivationSession getSession(int index) {
		return sessions.get(index);
	}
	
	public int getSessionCount() {
		return sessions.size();
	}
	
//	public CallTreeLayout getCallTree() {
//		return callTreeLayout;
//	}
	
	public DerivationResults nextInference(MethodProperty property) {
		Set<MethodExecution> unreflectedExecutions = activeSession.decideMethodProperty(property);
		// セッションを作る処理
		for (MethodExecution unreflectedExecution : unreflectedExecutions) {
			sessions.add(new DerivationSession(unreflectedExecution));
		}
		return null;
	}
	
	public DerivationResults firstInference() {
		HashSet<String> minus = minusTrace.getAllMethodSignatures();
		for (String plus : plusTrace.getAllMethodSignatures()) {
			if (!minus.contains(plus)) {
				System.out.println(plus);
				result.addMethodSignature(plus);
//				plusTrace.getMethodExecutions(plus);
			}
		}
		return result;
	}
	
	private ArrayList<Mark> readMarkFile(String path) {
		ArrayList<Mark> marks = new ArrayList<>();
		return marks;
	}
	
	public HashSet<MethodExecution> getMethodExecutions() {
		HashSet<MethodExecution> methodExecutions = new HashSet<>();
		for (String methodSignature : result.getMethodSignatures()) {
			methodExecutions.addAll(plusTrace.getMethodExecutions(methodSignature));
		}
		HashSet<MethodExecution> testExecutions = new HashSet<>();
		for (MethodExecution execution : methodExecutions) {
			testExecutions.add(execution);
			if (testExecutions.size() >= 10) break;
		}
//		return methodExecutions;
		return testExecutions;
	}
	
}
