package org.apache.ode.bpel.obj.migrate;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * compare two object for equality. default strategy:
 * for collections and maps, compare their contents
 * for POJO, 
 * 		if any custom equality comparator can handle it, then use it;
 * 		if it has an equals() method defined, use it.
 * 		or compare their non-transient accessible fields by reflection.
 * @author fangzhen
 *
 */
public class DeepEqualityHelper{

	private static final Logger __log = LoggerFactory.getLogger(ObjectTraverser.class);
    public boolean logFalseThrough = false;
    private Stack<String> st = new Stack<String>();
    
    private List<EqualityComparator> comparators = new LinkedList<EqualityComparator>();
    private Stack<Long> ongoing = new Stack<Long>();
    
    private Map<Long, Boolean> cache = new HashMap<Long, Boolean>();
    
    private final List<String> IGNORE_FIELDS = new ArrayList<String>();
    {
        // due to ODE-1023, we set all document element to null in compiled process models. Thus we need to exclude them
        // from the comparison because the were still set in old CBP files.
        IGNORE_FIELDS.add("protected org.w3c.dom.Element com.ibm.wsdl.AbstractWSDLElement.docEl");
    }
    
    public boolean deepEquals(Object obj1, Object obj2){
  //  	__log.debug("comparing Objects: " + obj1 + " and " + obj2); //will cause too much log
    	Boolean c = cachedRes(obj1, obj2);
    	if (c != null) {
    		return c;
    	}
    	Long h12 = hash(obj1, obj2);
    	if (ongoing.contains(h12)) {
    		return true;
    	}
    	ongoing.push(h12);
    	
		boolean n;
		if (isMap(obj1)){
			n = visitMap(obj1, obj2);
		}else if (isSet(obj1)){
			n = visitSet(obj1, obj2);
		}else if (isCollection(obj1)){
			n = visitCollection(obj1, obj2);
		}else if (isArray(obj1)){
			n = visitArray(obj1, obj2);
		}else{
			n = visitPojo(obj1, obj2);
		}
		cacheRes(obj1, obj2, n);
		ongoing.pop();
    	return n;
    }
    
	private void cacheRes(Object obj1, Object obj2, Boolean n) {
		cache.put(hash(obj1, obj2), n);
	}

	private Boolean cachedRes(Object obj1, Object obj2) {
		return cache.get(hash(obj1, obj2));
	}

	public Boolean visitMap(Object obj, Object other) {
		if (obj == other) return true;
		if (other == null) {
			if (!logFalseThrough){
				__log.debug("Unequal in Map: Object2 is null. " + st);
			}
			return false;
		}
		Map m1 = (Map)obj;
		Map m2 = null;
		try{
			m2 = (Map)other;
		}catch (ClassCastException e){
			if (!logFalseThrough){
				__log.debug("Unequal in Map: Object2 is not a map, it's a" + other.getClass() + "\n" + st);
			}
			return false;
		}
		if (m1.size() != m2.size()) {
			if (!logFalseThrough){
				__log.debug("Unequal in Map: size mismatch. " + st + 
					"\n size: " + m1.size() + " and " + m2.size());
			}
			return false;
		}
		Set ks1 = m1.keySet();
		Set ks2 = m2.keySet();
		for (Object k1 : ks1){
			st.push(k1.toString());
			Object k2 = contains(ks2, k1);
			if (k2 == null){
				if (!logFalseThrough){
					__log.debug("Unequal in Map: cant find key. " + st + "\n missing key: " + k1);
				}
				st.pop();
				return false;
			}
			Object o1 = m1.get(k1);
			Object o2 = m2.get(k2);
			if (o1 == null){
				if (!(o2 == null)){
					if (!logFalseThrough){
						__log.debug("Unequal in Map: mismatch, one is null" + st + 
							"\n When dealing with " + o1 + " and " + o2);
					}	
					st.pop();
					return false;
				}
			}

			st.pop();
			st.push(k1.toString() + ":" + o1.getClass().getSimpleName());
			
			Boolean e = deepEquals(o1, o2);
			if (!e) {
				st.pop();
				return false;
			}
			st.pop();
		}
		return true;
	}

	@SuppressWarnings("rawtypes")
	public Boolean visitSet(Object obj, Object other){
		if (obj == other) return true;
		if (other == null) {
			if (!logFalseThrough){
				__log.debug("Unequal in Set, Object2 is null. " + st);
			}
			return false;
		}
		
		Collection c1 = (Collection)obj;
		Collection c2 = null;
		try {
			c2 = (Collection)other;
		}catch(ClassCastException e){
			if (!logFalseThrough){
				__log.debug("Unequal in Set: Object2 is not a Set, it's a" + other.getClass() + "\n" + st);
			}
			return false;
		}
		if (c1.size() != c2.size()) {
			if (!logFalseThrough){
				__log.debug("Unequal in Set: size mismatch. " + st + 
					"\n. sizes are " + c1.size() + " and " + c2.size());
			}
			return false;
		}
		Iterator i1 = c1.iterator();
		while (i1.hasNext()){
			Object o1 = i1.next();
			st.push(":" + o1.getClass().getSimpleName());
			if (contains(c2, o1) == null) {
				if (!logFalseThrough){
					__log.debug("Unequal in Set: Object mismatch. " + st + 
						"\n" + "can't find " + o1);
				}
				st.pop();
				return false;
			}
			st.pop();
		}
		return true;
	}
	
	private Object contains(Collection c, Object t1) {
		Iterator itor = c.iterator();
		Object t2;
		logFalseThrough = true;
		while (itor.hasNext()){
			t2 = itor.next();
			if (deepEquals(t1, t2)) {
				logFalseThrough = false;
				return t2;
			}
		}
		logFalseThrough = false;
		return null;
	}

	@SuppressWarnings("rawtypes")
	public Boolean visitCollection(Object obj, Object other) {
		if (obj == other) return true;
		if (other == null) {
			if (!logFalseThrough){
				__log.debug("Unequal in Collection, Object2 is null. " + st);
			}
			return false;
		}
		
		Collection c = (Collection)obj;
		Collection c2 = null;
		try {
			c2 = (Collection)other;
		}catch(ClassCastException e){
			if (!logFalseThrough){
				__log.debug("Unequal in Collection: Object2 is not a Collection, it's a" + other.getClass() + "\n" + st);
			}
			return false;
		}
		if (c.size() != c2.size()) {
			if (!logFalseThrough){
				__log.debug("Unequal in Collection: size mismatch. " + st + 
					"\n. sizes are " + c.size() + " and " + c2.size());
			}
			return false;
		}

		Iterator i1 = c.iterator();
		Iterator i2 = c2.iterator();
		while (i1.hasNext()){
			Object o1 = i1.next();
			Object o2 = i2.next();
			st.push(":" + o1.getClass().getSimpleName());
			Boolean e = deepEquals(o1, o2);
			if (!e) {
				st.pop();
				return false;
			}
			st.pop();
		}
		return true;
	}

	public Boolean visitArray(Object obj, Object other) {
		throw new UnsupportedOperationException();
	}

	public Boolean visitPojo(Object obj, Object other) {
		EqualityComparator customComp = getCustomComparator(obj);
		if (customComp != null){
			return customComp.objectsEqual(obj, other);
		}
		if (obj == other) return true;
		if (other == null) {
			if (!logFalseThrough){
				__log.debug("Unequal in POJO: Object2 is null." + st);
			}
			return false;
		}
		if (obj.getClass() != other.getClass()) {
			if(!logFalseThrough){
				__log.debug("Unequal in POJO: type mistach. " + st + 
						"\nmismatched types are: " + obj.getClass().getSimpleName() + 
						" and " + other.getClass().getSimpleName());
			}
			return false;
		}
		try{
			obj.getClass().getDeclaredMethod("equals", Object.class);
			boolean e = obj.equals(other);
			if (!e){
				if (!logFalseThrough){
					__log.debug("Unequal in POJO: not equal by equals() method" + st); 
				}
			}
			return e;
		}catch (NoSuchMethodException e){
			return equalityByReflection(obj, other);
		}
	}

	private EqualityComparator getCustomComparator(Object obj) {
		for (EqualityComparator c : comparators){
			if (c.canHandle(obj)){
				return c;
			}
		}
		return null;
	}
	public Boolean equalityByReflection(Object obj, Object other) {
		List<Field> fields = MigUtils.getAllFields(obj.getClass());
		List<Field> fields2 = MigUtils.getAllFields(other.getClass());
		if (!fields.equals(fields2)){
			if (!logFalseThrough){
				__log.debug("Unequal: getFields() of two Object do not match " + st);
			}
			return false;
		}
		
		for (Field f : fields){
			f.setAccessible(true);
			if (((Modifier.TRANSIENT | Modifier.STATIC) & f.getModifiers()) != 0){
				continue; //skip transient fields
			}
			try {
				Object v2 = f.get(other);
				Object v1 = f.get(obj);
				if (v1 == null && v2 == null){
					continue;
				}
				
				if (IGNORE_FIELDS.contains(f.toString())) {
                    __log.debug("Ignoring field " + f.getName() + " with values " + v1 + " and " + v2);
				    
				    continue;
				}
				
				st.push(f.getName()+ ":" + f.getType().getSimpleName());				
				if (v1 == null || v2 == null){
					if (!logFalseThrough){
						__log.debug("Unequal: one field is null" + st + ".\n When dealing with " 
							+ v1 + " and " + v2);
					}
					st.pop();
					return false;
				}
				Boolean res = deepEquals(v1, v2);
				if (!res){
					st.pop();
					return false;
				}
				st.pop();
			} catch (Exception e) {
				//should not get here
				e.printStackTrace();
			}
		}
		return true;
	}

	/**
	 * determine if obj is collections that order doesn't matter.
	 * @param obj
	 * @return
	 */
	protected boolean isSet(Object obj) {
		return obj instanceof Set;
	}

	protected boolean isArray(Object old) {
		return old.getClass().isArray();
	}

	/**
	 * determine if obj is collections that order does matter.
	 * @param obj
	 * @return
	 */
	protected boolean isCollection(Object old) {
		return (old instanceof Collection) && !isSet(old);
	}

	protected boolean isMap(Object old) {
		return old instanceof Map;
	}

	private Long hash(Object obj1, Object obj2) {
		int h1 = System.identityHashCode(obj1);
		int h2 = System.identityHashCode(obj2);
		return ((long)h1) << 32 | h2;
	}
	
	public void addCustomComparator(EqualityComparator oe){
		comparators.add(0, oe);
		oe.setDeepEquality(this);
	}
    public Stack<String> getSt() {
		return st;
	}
}
