/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package benchmarks;

import com.google.caliper.Param;
import com.google.caliper.SimpleBenchmark;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.util.Arrays;

public class DeepArrayOpsBenchmark extends SimpleBenchmark {
    @Param({"1", "4", "16", "256", "2048"}) int arrayLength;

    private Object[] array;
    private Object[] array2;

    private Object[] array3;
    private Object[] array4;

    protected void setUp() throws Exception {
        array = new Object[arrayLength * 13];
        array2 = new Object[arrayLength * 13];
        for (int i = 0; i < arrayLength; i += 13) {
            array[i] = new IntWrapper(i);
            array2[i] = new IntWrapper(i);

            array[i + 1] = new16ElementObjectarray();
            array2[i + 1] = new16ElementObjectarray();

            array[i + 2] = new boolean[16];
            array2[i + 2] = new boolean[16];

            array[i + 3] = new byte[16];
            array2[i + 3] = new byte[16];

            array[i + 4] = new char[16];
            array2[i + 4] = new char[16];

            array[i + 5] = new short[16];
            array2[i + 5] = new short[16];

            array[i + 6] = new float[16];
            array2[i + 6] = new float[16];

            array[i + 7] = new long[16];
            array2[i + 7] = new long[16];

            array[i + 8] = new int[16];
            array2[i + 8] = new int[16];

            array[i + 9] = new double[16];
            array2[i + 9] = new double[16];

            // Subarray types are concrete objects.
            array[i + 10] = new16ElementArray(String.class, String.class);
            array2[i + 10] = new16ElementArray(String.class, String.class);

            array[i + 11] = new16ElementArray(Integer.class, Integer.class);
            array2[i + 11] = new16ElementArray(Integer.class, Integer.class);

            // Subarray types is an interface.
            array[i + 12] = new16ElementArray(CharSequence.class, String.class);
            array2[i + 12] = new16ElementArray(CharSequence.class, String.class);
        }
    }

    public void timeDeepHashCode(int reps) {
        for (int i = 0; i < reps; ++i) {
            Arrays.deepHashCode(array);
        }
    }

    public void timeEquals(int reps) {
        for (int i = 0; i < reps; ++i) {
            Arrays.deepEquals(array, array2);
        }
    }

    private static final Object[] new16ElementObjectarray() {
        Object[] array = new Object[16];
        for (int i = 0; i < 16; ++i) {
            array[i] = new IntWrapper(i);
        }

        return array;
    }

    @SuppressWarnings("unchecked")
    private static final <T, V> T[] new16ElementArray(Class<T> arrayType, Class<V> type)
            throws Exception {
        T[] array = (T []) Array.newInstance(type, 16);
        if (!arrayType.isAssignableFrom(type)) {
            throw new IllegalArgumentException(arrayType + " is not assignable from " + type);
        }

        Constructor<V> constructor = type.getDeclaredConstructor(String.class);
        for (int i = 0; i < 16; ++i) {
            array[i] = (T) constructor.newInstance(String.valueOf(i + 1000));
        }

        return array;
    }

    /**
     * A class that provides very basic equals() and hashCode() operations
     * and doesn't resort to memoization tricks like {@link java.lang.Integer}.
     *
     * Useful for providing equal objects that aren't the same (a.equals(b) but
     * a != b).
     */
    public static final class IntWrapper {
        private final int wrapped;

        public IntWrapper(int wrap) {
            wrapped = wrap;
        }

        @Override
        public int hashCode() {
            return wrapped;
        }

        @Override
        public boolean equals(Object o) {
            if (!(o instanceof IntWrapper)) {
                return false;
            }

            return ((IntWrapper) o).wrapped == this.wrapped;
        }
    }
}

