package unify;

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

import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;

public class FiniteClosureBuilder {
	
	private Set<UnifyPair> pairs = new HashSet<>();
	
	public void add(UnifyType sub, UnifyType sup) {
		pairs.add(new UnifyPair(sub, sup, PairOperator.SMALLER));
	}
	
	public IFiniteClosure getFiniteClosure() {
		return new FiniteClosure(pairs);
	}
	
	public void clear() {
		pairs = new HashSet<>();
	}
	
	public IFiniteClosure getCollectionExample() {
		TypeFactory tf = new TypeFactory();
		
		/* Collection */
		
		UnifyType collection = tf.getSimpleType("Collection");
		UnifyType set = tf.getSimpleType("Set", "T");
		//Type sortedSet = tf.getSimpleType("SortedSet", "T"); Sorted set bei den Unit-Tests vergessen
		// nachträgliches einfügen zu aufwendig
		UnifyType TreeSet = tf.getSimpleType("TreeSet", "T");
		UnifyType hashSet = tf.getSimpleType("HashSet", "T");
		UnifyType linkedHashSet = tf.getSimpleType("LinkedHashSet", "T");
		UnifyType queue = tf.getSimpleType("Queue", "T");
		UnifyType deque = tf.getSimpleType("Deque", "T");
		UnifyType linkedList = tf.getSimpleType("LinkedList", "T");
		UnifyType list = tf.getSimpleType("List", "T");
		UnifyType vector = tf.getSimpleType("Vector", "T");
		UnifyType stack = tf.getSimpleType("Stack", "T");
		UnifyType arrayList = tf.getSimpleType("ArrayList", "T");
		
		add(set, collection);
		//add(sortedSet, set);
		add(TreeSet, set);
		add(hashSet, set);
		add(linkedHashSet, set);
		
		add(queue, collection);
		add(deque, queue);
		add(linkedList, deque);
		add(list, collection);
		add(linkedList, list);
		add(vector, list);
		add(arrayList, list);
		add(stack, vector);
		
		/* Map */
		UnifyType map = tf.getSimpleType("Map", "K", "V");
		UnifyType sortedMap = tf.getSimpleType("SortedMap", "K", "V");
		UnifyType navigableMap = tf.getSimpleType("NavigableMap", "K", "V");
		UnifyType treeMap = tf.getSimpleType("TreeMap", "K", "V");
		UnifyType hashMap = tf.getSimpleType("HashMap", "K", "V");
		UnifyType hashtable = tf.getSimpleType("Hashtable", "K", "V");
		UnifyType linkedHashMap = tf.getSimpleType("LinkedHashMap", "K", "V");
		
		add(sortedMap, map);
		add(hashMap, map);
		add(hashtable, map);
		add(navigableMap, sortedMap);
		add(treeMap, navigableMap);
		add(linkedHashMap, hashMap);
		
		IFiniteClosure fc = getFiniteClosure();
		clear();
		return fc;
	}
}