package eu.dnetlib.contract.cp.comp;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.junit.Before;
import org.junit.Test;

import eu.dnetlib.contract.cp.comp.ComparatorManager;
import eu.dnetlib.contract.cp.comp.impl.CreatePullRSTypeComparatorModule;
import eu.dnetlib.resultset.CreatePullRSType;


/**
 * ComparatorManager test class.
 * @author mhorst
 *
 */
public class ComparatorManagerTest {

	ComparatorManager comparatorManager;
	
	@Before
	public void init() {
		comparatorManager = new ComparatorManager();
//		no modules registered
	}
	
	@Test
	public void testEqualsNoModules() {
		Object obj1 = null;
		Object obj2 = null;
		assertTrue(comparatorManager.equals(obj1, obj2));
		
		obj1 = new String("str1");
		obj2 = new String("str1");
		assertTrue(comparatorManager.equals(obj1, obj2));
		
		obj1 = null;
		obj2 = new String("str1");
		assertFalse(comparatorManager.equals(obj1, obj2));
		
		obj1 = new String("str1");
		obj2 = null;
		assertFalse(comparatorManager.equals(obj1, obj2));
		
		obj1 = new String("str1");
		obj2 = new String("str2");
		assertFalse(comparatorManager.equals(obj1, obj2));
		
		obj1 = new Integer(12);
		obj2 = String.valueOf(obj1);
		assertFalse(comparatorManager.equals(obj1, obj2));
	}
	
	@Test
	public void testEqualsComplexObjectNoModules() {
		CreatePullRSType obj1 = new CreatePullRSType();
		CreatePullRSType obj2 = new CreatePullRSType();
		assertFalse(comparatorManager.equals(obj1, obj2));
	}
	
	@SuppressWarnings("unchecked")
	@Test
	public void testEqualsCreatePullRSType() {
		comparatorManager.registerModule(new CreatePullRSTypeComparatorModule());
		CreatePullRSType obj1 = new CreatePullRSType();
		CreatePullRSType obj2 = new CreatePullRSType();
		assertTrue(comparatorManager.equals(obj1, obj2));
//		other tests are performed in CreatePullRSTypeComparatorModuleTest class
	}
	
	@Test
	public void testEqualsSimpleArrays() {
		String[] array1 = new String[] {"aaa","bbb","ccc"};
		String[] array2 = new String[] {"aaa","bbb","ccc"};
		assertFalse(array1.equals(array2));
		assertTrue(Arrays.equals(array1, array2));
		assertTrue(comparatorManager.equals(array1,array2));
		assertFalse(comparatorManager.equals("xxx",array2));
		assertFalse(comparatorManager.equals(array1,"xxx"));
		assertFalse(comparatorManager.equals(array1,new String[] {"aaa","bbb","ccc","ddd"}));
		assertFalse(comparatorManager.equals(array1,new String[] {"bbb","ccc","ddd"}));
	}
	
	@SuppressWarnings("unchecked")
	@Test
	public void testEqualsComplexArrays() {
		CreatePullRSType[] array1 = new CreatePullRSType[] {new CreatePullRSType(), new CreatePullRSType()};
		CreatePullRSType[] array2 = new CreatePullRSType[] {new CreatePullRSType(), new CreatePullRSType()};
		assertTrue(array1 instanceof Object[]);
		assertFalse(array1.equals(array2));
//		lack of comparator
		assertFalse(Arrays.equals(array1, array2));
		assertFalse(comparatorManager.equals(array1,array2));
//		registering comparator module
		comparatorManager.registerModule(new CreatePullRSTypeComparatorModule());
		assertTrue(comparatorManager.equals(array1,array2));
		CreatePullRSType createPullRSType = new CreatePullRSType();
		createPullRSType.setTotal(10);
		CreatePullRSType[] array3 = new CreatePullRSType[] {new CreatePullRSType(), createPullRSType};
		assertFalse(comparatorManager.equals(array1,array3));
		assertTrue(comparatorManager.equals(array3,array3));
	}
	
	@Test
	public void testEqualsSimpleCollections() {
		Collection<String> col1 = new ArrayList<String>();
		col1.add("aaa");
		col1.add("bbb");
		col1.add("ccc");
		Collection<String> col2 = new ArrayList<String>();
		col2.add("aaa");
		col2.add("bbb");
		col2.add("ccc");
		assertTrue(col1.equals(col2));
		assertTrue(comparatorManager.equals(col1,col2));
		assertFalse(comparatorManager.equals("xxx",col2));
		assertFalse(comparatorManager.equals(col1,"xxx"));
		col2.add("ddd");
		assertFalse(comparatorManager.equals(col1,col2));
		col1.add("ddd");
		assertTrue(comparatorManager.equals(col1,col2));
	}
	
	@SuppressWarnings("unchecked")
	@Test
	public void testEqualsComplexCollections() {
		Collection<CreatePullRSType> col1 = new ArrayList<CreatePullRSType>();
		col1.add(new CreatePullRSType());
		col1.add(new CreatePullRSType());
		col1.add(new CreatePullRSType());
		Collection<CreatePullRSType> col2 = new ArrayList<CreatePullRSType>();
		col2.add(new CreatePullRSType());
		col2.add(new CreatePullRSType());
		col2.add(new CreatePullRSType());
		assertFalse(col1.equals(col2));
		assertFalse(comparatorManager.equals(col1,col2));
//		registering comparator module
		comparatorManager.registerModule(new CreatePullRSTypeComparatorModule());
		assertTrue(comparatorManager.equals(col1,col2));
		assertFalse(comparatorManager.equals("xxx",col2));
		assertFalse(comparatorManager.equals(col1,"xxx"));
		col2.add(new CreatePullRSType());
		assertFalse(comparatorManager.equals(col1,col2));
		col1.add(new CreatePullRSType());
		assertTrue(comparatorManager.equals(col1,col2));
		CreatePullRSType createPullRSType1 = new CreatePullRSType();
		createPullRSType1.setTotal(10);
		CreatePullRSType createPullRSType2 = new CreatePullRSType();
		createPullRSType2.setTotal(20);
		col1.add(createPullRSType1);
		col2.add(createPullRSType2);
		assertFalse(comparatorManager.equals(col1,col2));
	}
	
	@Test
	public void testEqualsSimpleMaps() {
		Map<String,Integer> map1 = new HashMap<String,Integer>();
		map1.put("aaa",111);
		map1.put("bbb",222);
		map1.put("ccc",333);
		Map<String,Integer> map2 = new HashMap<String,Integer>();
		map2.put("aaa",111);
		map2.put("bbb",222);
		map2.put("ccc",333);
		assertTrue(map1.equals(map2));
		assertTrue(comparatorManager.equals(map1,map2));
		assertFalse(comparatorManager.equals("xxx",map2));
		assertFalse(comparatorManager.equals(map1,"xxx"));
		map2.put("ddd",444);
		assertFalse(comparatorManager.equals(map1,map2));
		map1.put("ddd",444);
		assertTrue(comparatorManager.equals(map1,map2));
	}
}
