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.canHanle(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;
	}
}
