package org.ntlab.traceanalyzer;

import java.util.ArrayList;
import java.util.Stack;

import org.ntlab.trace.IMethodExecutionVisitor;
import org.ntlab.trace.MethodExecution;
import org.ntlab.trace.ThreadInstance;

public class MarkedMethodExecutionVisitor implements IMethodExecutionVisitor {
	private ArrayList<MarkedThread> markedThreads = new ArrayList<MarkedThread>();
	private ArrayList<MarkedMethodExecution> topMethodExecutions = null;
	private Stack<MarkedMethodExecution> callStack = new Stack<MarkedMethodExecution>();

	@Override
	public boolean preVisitThread(ThreadInstance thread) {
		topMethodExecutions = new ArrayList<MarkedMethodExecution>();		
		return false;
	}

	@Override
	public boolean postVisitThread(ThreadInstance thread) {
		if (topMethodExecutions.size() > 0) markedThreads.add(new MarkedThread(thread.getId(), topMethodExecutions));
		return false;
	}

	@Override
	public boolean preVisitMethodExecution(MethodExecution methodExecution) {
		MarkedMethodExecution child = new MarkedMethodExecution(methodExecution);
		if (!callStack.isEmpty()) {
			MarkedMethodExecution parent = callStack.peek();
			parent.addChild(child);
		}
		callStack.push(child);
		return false;
	}

	@Override
	public boolean postVisitMethodExecution(MethodExecution methodExecution, ArrayList<MethodExecution> children) {
		MarkedMethodExecution markedMethodExecution = callStack.pop();
		if (callStack.isEmpty()) {
			topMethodExecutions.add(markedMethodExecution);
		}
		return false;
	}

	public ArrayList<MarkedThread> getMarkedThreads() {
		return markedThreads;
	}

}
