/*
 * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
 * @test
 * @bug     4655503
 * @summary Test for array cloning and slicing methods.
 * @author  John Rose
 */

import java.util.*;
import java.lang.reflect.*;

public class CopyMethods {
    static int muzzle;  // if !=0, suppresses ("muzzles") messages

    static int maxLen = 40;  // maximum length of test arrays
    static int shortStepsNear = 4;  // interesting span near critical values
    static int downShift = 3;

    static int testCasesRun = 0;
    static long consing = 0;

    // very simple tests, mainly to test the framework itself
    static void simpleTests() {
        int[] a = (int[]) makeArray(3, int.class);
        if (muzzle == 0)
            System.out.println("int[] a = "+Arrays.toString(a));
        check(a.length == 3);
        check(a[0] == testValues[0]);
        check(a[1] == testValues[1]);
        check(a[2] == testValues[2]);
        checkArray(a, int.class, 3, 0, 3);
        // negative test of testing framework:
        for (int bad = -2; bad < a.length; bad++) {
            try {
                int[] aa = a.clone();
                if (bad < 0)  aa = new int[4];
                else          aa[bad] = 0;
                ++muzzle;
                // the following check should fail!
                if (bad == -2)
                    checkArray(new String[3], int.class, 0, 0, a.length);
                else
                    checkArray(aa, int.class, 0, 0, a.length);
                throw new Error("Should Not Reach Here");
            } catch (RuntimeException ee) {
                --muzzle;
                if (muzzle == 0)
                    System.out.println("Expected: "+ee);
            }
        }
        checkArray(Arrays.copyOf(a, 0), int.class, 0, 0, 3);
        checkArray(Arrays.copyOf(a, 1), int.class, 1, 0, 3);
        checkArray(Arrays.copyOf(a, 2), int.class, 2, 0, 3);
        checkArray(Arrays.copyOf(a, 3), int.class, 3, 0, 3);
        checkArray(Arrays.copyOf(a, 4), int.class, 4, 0, 3);

        // quick test of copyOfRange
        int[] ar = Arrays.copyOfRange(a, 1, 3);
        check(ar.length == 2);
        check(ar[0] == a[1]);
        check(ar[1] == a[2]);
        checkArray(ar, int.class, 2, 1, 2);
        ar = Arrays.copyOfRange(a, 2, 4);
        check(ar.length == 2);
        check(ar[0] == a[2]);
        check(ar[1] == 0);
        checkArray(ar, int.class, 2, 2, 1);
        ar = Arrays.copyOfRange(a, 3, 5);
        check(ar.length == 2);
        check(ar[0] == 0);
        check(ar[1] == 0);
        checkArray(ar, int.class, 2, 3, 0);
        byte[] ba = (byte[]) makeArray(3, byte.class);
        if (muzzle == 0)
            System.out.println("byte[] ba = "+Arrays.toString(ba));
        for (int j = 0; j <= ba.length+2; j++) {
            byte[] bb = Arrays.copyOf(ba, j);
            if (muzzle == 0)
                System.out.println("copyOf(ba,"+j+") = "+
                                   Arrays.toString(bb));
            checkArray(bb, byte.class, j, 0, ba.length);
            byte[] bbr = Arrays.copyOfRange(ba, 0, j);
            check(Arrays.equals(bb, bbr));
        }
        for (int i = 0; i <= a.length; i++) {
            for (int j = i; j <= a.length+2; j++) {
                byte[] br = Arrays.copyOfRange(ba, i, j);
                if (muzzle == 0)
                    System.out.println("copyOfRange(ba,"+i+","+j+") = "+
                                       Arrays.toString(br));
                checkArray(br, byte.class, j-i, i, ba.length-i);
            }
        }
        String[] sa = (String[]) makeArray(3, String.class);
        if (muzzle == 0)
            System.out.println("String[] sa = "+Arrays.toString(sa));
        check(sa[0].equals(Integer.toHexString(testValues[0])));
        check(sa[1].equals(Integer.toHexString(testValues[1])));
        check(sa[2].equals(Integer.toHexString(testValues[2])));
        checkArray(sa, String.class, sa.length, 0, sa.length);
        String[] sa4 = Arrays.copyOf(sa, sa.length+1);
        check(sa4[0] == sa[0]);
        check(sa4[1] == sa[1]);
        check(sa4[2] == sa[2]);
        check(sa4[sa.length] == null);
        checkArray(sa4, String.class, sa4.length, 0, sa.length);
        String[] sr4 = Arrays.copyOfRange(sa, 1, 5);
        check(sr4[0] == sa[1]);
        check(sr4[1] == sa[2]);
        check(sr4[2] == null);
        check(sr4[3] == null);
        checkArray(sr4, String.class, 4, 1, sa.length-1);
        if (muzzle == 0)
            System.out.println("simpleTests done");
    }

    // the framework:  a fixed series of test values
    static final int[] testValues;
    static {
        testValues = new int[1000];
        Random r = new Random();
        for (int i = 0; i < testValues.length; i++) {
            testValues[i] = r.nextInt();
        }
    }
    /** Return a canonical test value of a desired index and type.
     *  The original test values are random ints.  Derive other test
     *  values as follows:
     *  <pre>
     *  int tv = testValues[i]
     *  (C)tv                    C is byte, short, char, long, float, double
     *  (tv&1)!=0                C is boolean
     *  (Integer)tv              C is Object and tv%16 != 0
     *  null                     C is Object and tv%16 == 0
     *  Integer.toHexString(tv)  C is String and tv != 0
     *  null                     C is String and tv == 0
     *  </pre>
     *  are derived by ordinary Java coercions, except that boolean
     *  samples the LSB of the int value, and String is the hex numeral.
     *
     *  (Also, the 0th String is null, and the 0th Object mod 16 is null,
     *  regardless of the original int test value.)
     */
    static Object testValue(int i, Class<?> c) {
        int tv = testValues[i % testValues.length];
        if (i >= testValues.length)  tv ^= i;
        // Turn the canonical int to a float, boolean, String, whatever:
        return invoke(coercers.get(c), tv);
    }
    /** Build a test array of the given length,
     *  packed with a subsequence of the test values.
     *  The first element of the array is always testValue(0).
     */
    static Object makeArray(int len, Class<?> c) {
        Object a = Array.newInstance(c, len);
        for (int i = 0; i < len; i++) {
            Array.set(a, i, testValue(i, c));
        }
        return a;
    }
    /** Check that the given array has the required length.
     *  Check also that it is packed, up to firstNull, with
     *  a particular subsequence of the canonical test values.
     *  The subsequence must begin with a[0] == testValue(offset).
     *  At a[firstNull] and beyond, the array must contain null values.
     */
    static void checkArray(Object a, Class<?> c, int requiredLen, int offset, int firstNull) {
        check(c == a.getClass().getComponentType());
        Object nullValue = nullValues.get(c);
        // Note:  asserts in here are not part of the test program.
        // They verify the integrity of the test method itself.
        assert(nullValues.containsKey(c));

        int misses = 0;
        int firstMiss = -1;
        // Check required length first.
        int length = Array.getLength(a);
        if (length != requiredLen && requiredLen != -1) {
            if (muzzle == 0)
                System.out.println("*** a.length = "+length+" != "+requiredLen);
            ++misses;
        }

        for (int i = 0; i < length; i++) {
            Object tv = (i >= firstNull) ? nullValue : testValue(i+offset, c);
            Object ai = Array.get(a, i);
            if (!eq(ai, tv)) {
                if (muzzle == 0)
                    System.out.println("*** a["+i+"] = "+ai+" != "+tv);
                if (misses == 0)  firstMiss = i;
                if (++misses > 10)  break;
            }
        }
        if (misses != 0) {
            Method toString = toStrings.get(c);
            if (toString == null)  toString = toStrings.get(Object.class);
            throw new RuntimeException("checkArray failed at "+firstMiss
                                       +" "+c+"[]"
                                       +" : "+invoke(toString, a));
        }
    }
    // Typical comparison helper.  Why isn't this a method somewhere.
    static boolean eq(Object x, Object y) {
        return x == null? y == null: x.equals(y);
    }
    // Exception-ignoring invoke function.
    static Object invoke(Method m, Object... args) {
        Exception ex;
        try {
            return m.invoke(null, args);
        } catch (InvocationTargetException ee) {
            ex = ee;
        } catch (IllegalAccessException ee) {
            ex = ee;
        } catch (IllegalArgumentException ee) {
            ex = ee;
        }
        ArrayList<Object> call = new ArrayList<Object>();
        call.add(m); Collections.addAll(call, args);
        throw new RuntimeException(call+" : "+ex);
    }
    // version of assert() that runs unconditionally
    static void check(boolean z) {
        if (!z)  throw new RuntimeException("check failed");
    }


    /** Run about 10**5 distinct parameter combinations
     *  on copyOf and copyOfRange.  Use all primitive types,
     *  and String and Object.
     *  Try to all critical values, looking for fencepost errors.
     */
    static void fullTests(int maxLen, Class<?> c) {
        Method cloner      = cloners.get(c);
        assert(cloner != null) : c;
        Method cloneRanger = cloneRangers.get(c);
        // Note:  asserts in here are not part of the test program.
        // They verify the integrity of the test method itself.
        assert(cloneRanger != null) : c;
        for (int src = 0; src <= maxLen; src = inc(src, 0, maxLen)) {
            Object a = makeArray(src, c);
            for (int x : new ArrayList<Integer>()) {}
            for (int j = 0; j <= maxLen; j = inc(j, src, maxLen)) {
                // b = Arrays.copyOf(a, j);
                Object b = invoke(cloner, a, j);
                checkArray(b, c, j, 0, src);
                testCasesRun++;
                consing += j;

                int maxI = Math.min(src, j);
                for (int i = 0; i <= maxI; i = inc(i, src, maxI)) {
                    // r = Arrays.copyOfRange(a, i, j);
                    Object r = invoke(cloneRanger, a, i, j);
                    checkArray(r, c, j-i, i, src-i);
                    //System.out.println("case c="+c+" src="+src+" i="+i+" j="+j);
                    testCasesRun++;
                    consing += j-i;
                }
            }
        }
    }
    // Increment x by at least one.  Increment by a little more unless
    // it is near a critical value, either zero, crit1, or crit2.
    static int inc(int x, int crit1, int crit2) {
        int D = shortStepsNear;
        if (crit1 > crit2) { int t = crit1; crit1 = crit2; crit2 = t; }
        assert(crit1 <= crit2);
        assert(x <= crit2);  // next1 or next2 must be the limit value
        x += 1;
        if (x > D) {
            if (x < crit1-D) {
                x += (x << 1) >> downShift;  // giant step toward crit1-D
                if (x > crit1-D)  x = crit1-D;
            } else if (x >= crit1+D && x < crit2-D) {
                x += (x << 1) >> downShift;  // giant step toward crit2-D
                if (x > crit2-D)  x = crit2-D;
            }
        }
        return x;
    }

    public static void main(String[] av) {
        boolean verbose = (av.length != 0);
        muzzle = (verbose? 0: 1);
        if (muzzle == 0)
            System.out.println("test values: "+Arrays.toString(Arrays.copyOf(testValues, 5))+"...");

        simpleTests();

        muzzle = 0;  // turn on print statements (affects failures only)

        fullTests();
        if (verbose)
            System.out.println("ran "+testCasesRun+" tests, avg len="
                               +(float)consing/testCasesRun);

        // test much larger arrays, more sparsely
        maxLen = 500;
        shortStepsNear = 2;
        downShift = 0;
        testCasesRun = 0;
        consing = 0;
        fullTests();
        if (verbose)
            System.out.println("ran "+testCasesRun+" tests, avg len="
                               +(float)consing/testCasesRun);
    }

    static void fullTests() {
        for (Class<?> c : allTypes) {
            fullTests(maxLen, c);
        }
    }

    // We must run all the our tests on each of 8 distinct primitive types,
    // and two reference types (Object, String) for good measure.
    // This would be a pain to write out by hand, statically typed.
    // So, use reflection.  Following are the tables of methods we use.
    // (The initial simple tests exercise enough of the static typing
    // features of the API to ensure that they compile as advertised.)

    static Object  coerceToObject(int x) { return (x & 0xF) == 0? null: new Integer(x); }
    static String  coerceToString(int x) { return (x == 0)? null: Integer.toHexString(x); }
    static Integer coerceToInteger(int x) { return (x == 0)? null: x; }
    static byte    coerceToByte(int x) { return (byte)x; }
    static short   coerceToShort(int x) { return (short)x; }
    static int     coerceToInt(int x) { return x; }
    static long    coerceToLong(int x) { return x; }
    static char    coerceToChar(int x) { return (char)x; }
    static float   coerceToFloat(int x) { return x; }
    static double  coerceToDouble(int x) { return x; }
    static boolean coerceToBoolean(int x) { return (x&1) != 0; }

    static Integer[] copyOfIntegerArray(Object[] a, int len) {
        // This guy exercises the API based on a type-token.
        // Note the static typing.
        return Arrays.copyOf(a, len, Integer[].class);
    }
    static Integer[] copyOfIntegerArrayRange(Object[] a, int m, int n) {
        // This guy exercises the API based on a type-token.
        // Note the static typing.
        return Arrays.copyOfRange(a, m, n, Integer[].class);
    }

    static final List<Class<?>> allTypes
        = Arrays.asList(new Class<?>[]
                        {   Object.class, String.class, Integer.class,
                            byte.class, short.class, int.class, long.class,
                            char.class, float.class, double.class,
                            boolean.class
                        });
    static final HashMap<Class<?>,Method> coercers;
    static final HashMap<Class<?>,Method> cloners;
    static final HashMap<Class<?>,Method> cloneRangers;
    static final HashMap<Class<?>,Method> toStrings;
    static final HashMap<Class<?>,Object> nullValues;
    static {
        coercers = new HashMap<Class<?>,Method>();
        Method[] testMethods = CopyMethods.class.getDeclaredMethods();
        Method cia = null, ciar = null;
        for (int i = 0; i < testMethods.length; i++) {
            Method m = testMethods[i];
            if (!Modifier.isStatic(m.getModifiers()))  continue;
            Class<?> rt = m.getReturnType();
            if (m.getName().startsWith("coerceTo") && allTypes.contains(rt))
                coercers.put(m.getReturnType(), m);
            if (m.getName().equals("copyOfIntegerArray"))
                cia = m;
            if (m.getName().equals("copyOfIntegerArrayRange"))
                ciar = m;
        }
        Method[] arrayMethods = Arrays.class.getDeclaredMethods();
        cloners      = new HashMap<Class<?>,Method>();
        cloneRangers = new HashMap<Class<?>,Method>();
        toStrings    = new HashMap<Class<?>,Method>();
        for (int i = 0; i < arrayMethods.length; i++) {
            Method m = arrayMethods[i];
            if (!Modifier.isStatic(m.getModifiers()))  continue;
            Class<?> rt = m.getReturnType();
            if (m.getName().equals("copyOf")
                && m.getParameterTypes().length == 2)
                cloners.put(rt.getComponentType(), m);
            if (m.getName().equals("copyOfRange")
                && m.getParameterTypes().length == 3)
                cloneRangers.put(rt.getComponentType(), m);
            if (m.getName().equals("toString")) {
                Class<?> pt = m.getParameterTypes()[0];
                toStrings.put(pt.getComponentType(), m);
            }
        }
        cloners.put(String.class, cloners.get(Object.class));
        cloneRangers.put(String.class, cloneRangers.get(Object.class));
        assert(cia != null);
        cloners.put(Integer.class, cia);
        assert(ciar != null);
        cloneRangers.put(Integer.class, ciar);
        nullValues = new HashMap<Class<?>,Object>();
        for (Class<?> c : allTypes) {
            nullValues.put(c, invoke(coercers.get(c), 0));
        }
    }
}
