package bytecode.simplifyalgo;

import static org.junit.Assert.*;

import java.util.HashMap;
import java.util.HashSet;

import org.junit.BeforeClass;
import org.junit.Test;
import org.objectweb.asm.Type;

import de.dhbwstuttgart.bytecode.TPHExtractor;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.utilities.Simplify;
/**
 * 
 * @author Fayez Abu Alia
 *
 */
public class SimpleCycle {
	private static TPHExtractor tphExtractor;
	private static String methName;
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		tphExtractor = new TPHExtractor();
		// A < B
		TPHConstraint c1 = new ExtendsConstraint("A", "B", Relation.EXTENDS);
		// B < A
		TPHConstraint c2 = new ExtendsConstraint("B", "A", Relation.EXTENDS);
		// name
		methName = "m";
		tphExtractor.allCons.add(c1);
		tphExtractor.allCons.add(c2);
		
	}

	@Test
	public void test() {
		HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
		HashSet<String> equals = new HashSet<>();
		equals.add("A");
		equals.add("B");
		TPHConstraint k = new ExtendsConstraint("B", Type.getInternalName(Object.class), Relation.EXTENDS);
		result.put(k, equals);
		
		HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor);
		boolean areEquals = areMapsEqual(result, sim);
		assertTrue(areEquals);
	}
	
	public static boolean areMapsEqual(HashMap<TPHConstraint, HashSet<String>> m1, HashMap<TPHConstraint, HashSet<String>> m2) {
		
		for(TPHConstraint c : m1.keySet()) {
			for(TPHConstraint c2 : m2.keySet()) {
				if(c.getLeft().equals(c2.getLeft()) && c.getRight().equals(c2.getRight()) && c.getRel()==c2.getRel()) {
					HashSet<String> eq1 = m1.get(c);
					HashSet<String> eq2 = m2.get(c2);
					
					if((eq1 == null && eq2 != null) || (eq1 != null && eq2 == null))
						return false;
					if(eq1 != null) {
						if(eq1.size() != eq2.size())
							return false;
						
						for(String tph:eq1) {
							if(!eq2.contains(tph))
								return false;
						}
					}
				}
			}
			
		}
		return true;
	}

}