/*
 *******************************************************************************
 * Copyright (C) 2006, International Business Machines Corporation and         *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */

package com.ibm.icu.tests;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale;

import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;

import junit.framework.TestCase;

/**
 * Implement boilerplate tests.
 * Currently there is only one method, testEHCS, which tests equals, hashCode, 
 * clone, and serialization.
 */
public abstract class ICUTestCase extends TestCase {
    private static final Object[] EMPTY_ARGS = {};
    private static final Class[] EMPTY_CLASSES = {};
        
    private static final Locale oldLocale = Locale.getDefault();
    private static final ULocale oldULocale = ULocale.getDefault();
    private static final java.util.TimeZone oldJTimeZone = java.util.TimeZone.getDefault();
    private static final TimeZone oldITimeZone = TimeZone.getDefault();
                
    // TODO: what's the best way to check this?
    public static final boolean testingWrapper = true;

    protected void setUp() throws Exception {
        super.setUp();
        Locale.setDefault(Locale.US);
        ULocale.setDefault(ULocale.US);
        java.util.TimeZone.setDefault(java.util.TimeZone.getTimeZone("PST"));
        TimeZone.setDefault(TimeZone.getTimeZone("PST"));
    }
        
    protected void tearDown() throws Exception {
        ULocale.setDefault(oldULocale);
        Locale.setDefault(oldLocale);
        TimeZone.setDefault(oldITimeZone);
        java.util.TimeZone.setDefault(oldJTimeZone);
        super.tearDown();
    }

    private static final Object test = new Object();
        
    /**
     * Assert that two objects are _not_ equal.  Curiously missing from Assert.
     * @param lhs an object to test, may be null
     * @param rhs an object to test, may be null
     */
    public static void assertNotEqual(Object lhs, Object rhs) {
        if (lhs == null) {
            if (rhs == null) fail("null equals null");
        } else {
            if (lhs.equals(rhs)) {
                fail(lhs.toString() + " equals " + rhs);
            }
        }
    }
        
    public static void assertNotEqual(long lhs, long rhs) {
        if (lhs == rhs) {
            fail("values are equal: " + lhs);
        }
    }
        
    /**
     * Test whether equality, hashCode, clone, and serialization work as expected.  
     * Equals(Object) is assumed to return false (not throw an exception) if passed 
     * null or an object of an incompatible class.
     * Hashcodes must be equal iff the two objects compare equal.  No attempt is made to
     * evaluate the quality of the hashcode distribution, so (in particular) degenerate 
     * hashcode implementations will pass this test.
     * Clone will be tested if the method "clone" is public on the class of obj.  
     * It is assumed to return an object that compares equal to obj.
     * Serialization will be tested if object implements Serializable or Externalizable.
     * It is assumed the serialized/deserialized object compares equal to obj.
     * @param obj the object to test
     * @param eq an object that should compare equal to, but is not the same as, obj.  
     *     it should be assignable to the class of obj.
     * @param neq a non-null object that should not compare equal to obj.  
     *     it should be assignable to the class of obj.
     */
    public static void testEHCS(Object obj, Object eq, Object neq) {
        if (obj == null || eq == null || neq == null) {
            throw new NullPointerException();
        }
        Class cls = obj.getClass();
        if (!(cls.isAssignableFrom(eq.getClass()) && cls.isAssignableFrom(neq.getClass()))) {
            throw new IllegalArgumentException("unassignable classes");
        }
                
        // reflexive
        assertEquals(obj, obj);
                
        // should return false, not throw exception
        assertNotEqual(obj, test);
        assertNotEqual(obj, null);
                
        // commutative
        assertEquals(obj, eq);
        assertEquals(eq, obj);
                
        assertNotEqual(obj, neq);
        assertNotEqual(neq, obj);
                
        // equal objects MUST have equal hashes, unequal objects MAY have equal hashes
        assertEquals(obj.hashCode(), eq.hashCode());
                
        Object clone = null;
        try {
            // look for public clone method and call it if available
            Method method_clone = cls.getMethod("clone", EMPTY_CLASSES);
            clone = method_clone.invoke(obj, EMPTY_ARGS);
            assertNotNull(clone);
        }
        catch(NoSuchMethodException e) {
            // ok
        }
        catch(InvocationTargetException e) {
            // ok
        }
        catch(IllegalAccessException e) {
            // ok
        }
                
        if (clone != null) {
            assertEquals(obj, clone);
            assertEquals(clone, obj);
        }
                
        if (obj instanceof Serializable || obj instanceof Externalizable) {
            Object ser = null;
            try {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(bos);
                oos.writeObject(clone);
                oos.close();
                                
                ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
                ObjectInputStream ois = new ObjectInputStream(bis);
                ser = ois.readObject();
                ois.close();
            }
            catch(IOException e) {
                System.err.println(e.getMessage());
                throw new RuntimeException(e);
            }
            catch(ClassNotFoundException e) {
                System.err.println(e.getMessage());
                throw new RuntimeException(e);
            }
                        
            if (ser != null) {
                assertEquals(obj, ser);
                assertEquals(ser, obj);
                assertEquals(obj.hashCode(), ser.hashCode());
            }
        }
    }

    /**
     * Fail if the arrays are not equal.  To be equal, the arrays must
     * be the same length, and each element in the left array must compare
     * equal to the corresponding element of the right array.
     * Also fails if one of the objects is not an array.
     * @param lhs the left array
     * @param rhs the right array
     */
    public static void assertArraysEqual(Object lhs, Object rhs) {
        Class lcls = lhs.getClass();
        Class rcls = rhs.getClass();
        if (!(lcls.isArray() && rcls.isArray())) {
            fail("objects are not arrays");
        }
        String result = arraysAreEqual(lhs, rhs);
        if (result != null) {
            fail(result);
        }
    }

    /**
     * Fail if the arrays are equal.  Also fails if one or the other 
     * argument is not an array.
     * @param lhs the left array
     * @param rhs the right array
     */
    public static void assertArraysNotEqual(Object lhs, Object rhs) {
        Class lcls = lhs.getClass();
        Class rcls = rhs.getClass();
        if (!(lcls.isArray() && rcls.isArray())) {
            fail("objects are not arrays");
        }
        String result = arraysAreEqual(lhs, rhs);
        if (result == null) {
            fail("arrays are equal");
        }
    }
        
    // slow but general
    private static String arraysAreEqual(Object lhsa, Object rhsa) {
        int lhsl = Array.getLength(lhsa);
        int rhsl = Array.getLength(rhsa);
        if (lhsl != rhsl) {
            return "length " + lhsl + " != " + rhsl;
        }
        boolean lhsaA = lhsa.getClass().getComponentType().isArray();
        boolean rhsaA = rhsa.getClass().getComponentType().isArray();
        if (lhsaA != rhsaA) {
            return (lhsaA ? "" : "non-") + "array != " + (rhsaA ? "" : "non-") + "array";
        }
        for (int i = 0; i < lhsl; ++i) {
            Object lhse = Array.get(lhsa, i);
            Object rhse = Array.get(rhsa, i);
            if (lhse == null) {
                if (rhse != null) {
                    return "null != " + rhse;
                }
            } else {
                if (lhsaA) {
                    String result = arraysAreEqual(lhse, rhse);
                    if (result != null) {
                        if (result.charAt(0) != '[') {
                            result = " " + result;
                        }
                        return "[" + i + "]" + result;
                    }
                } else {
                    if (!lhse.equals(rhse)) {
                        return lhse.toString() + " != " + rhse;
                    }
                }
            }
        }
        return null;
    }
        
    // much more painful and slow than it should be... partly because of the
    // oddness of clone, partly because arrays don't provide a Method for 
    // 'clone' despite the fact that they implement it and make it public.
    public static Object cloneComplex(Object obj) {
        Object result = null;
        if (obj != null) {
            Class cls = obj.getClass();
            if (cls.isArray()) {
                int len = Array.getLength(obj);
                Class typ = cls.getComponentType();
                result = Array.newInstance(typ, len);
                boolean prim = typ.isPrimitive();
                for (int i = 0; i < len; ++i) {
                    Object elem = Array.get(obj, i);
                    Array.set(result, i, prim ? elem : cloneComplex(elem));
                }
            } else {
                result = obj; // default
                try {
                    Method cloneM = cls.getMethod("clone", null);
                    result = cloneM.invoke(obj, null);
                }
                catch (NoSuchMethodException e) {
                }
                catch (IllegalAccessException e) {
                }
                catch (InvocationTargetException e) {
                }
            }
        }
        return result;
    }
}
