package org.bdware.analysis;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class BreadthFirstSearch<R extends AnalysisResult, T extends AnalysisTarget> {
	public Map<T, AnalysisResult> results;
	protected List<T> toAnalysis;

	public abstract R execute(T t);

	public abstract Collection<T> getSuc(T t);

	public BreadthFirstSearch() {
		results = new HashMap<T, AnalysisResult>();
	}

	public Map<T, AnalysisResult> analysis() {
		results.clear();
		T current = null;
		for (int i = 0; i < toAnalysis.size(); i++) {
			current = toAnalysis.get(i);
			current.setInList(false);
			AnalysisResult preResult = results.get(current);
			AnalysisResult sucResult = execute(current);

			if (preResult == null || !preResult.covers(sucResult)) {
				AnalysisResult cloneResult = sucResult.clone();
				if (cloneResult != null) {
					results.put(current, cloneResult);
				}
				Collection<T> sucs = getSuc(current);
				for (T next : sucs) {

					if (toAnalysis.contains(next)) {
						//results.remove(next);
						//toAnalysis.remove(next);
					}
					if (!next.inList()) {
						toAnalysis.add(next);
						next.setInList(true);
					}
				}
			}
		}
		return results;
	}

	public int getListLength() {
		return toAnalysis.size();
	}

	public void setToAnalysis(List<T> l) {
		toAnalysis = l;
	}
}
