/*
 * Copyright (C) 2018 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.
 */

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.VarHandle;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class VarHandleUnitTestHelpers {
    public static boolean isRunningOnAndroid() {
        return System.getProperty("java.vm.vendor").contains("Android");
    }

    public static boolean is64Bit() {
        // The behaviour of certain accessors depends on the ISA word size.
        if (isRunningOnAndroid()) {
            try {
                Class<?> runtimeClass = Class.forName("dalvik.system.VMRuntime");
                MethodHandle getRuntimeMH =
                        MethodHandles.lookup()
                                .findStatic(
                                        runtimeClass,
                                        "getRuntime",
                                        MethodType.methodType(runtimeClass));
                Object runtime = getRuntimeMH.invoke();
                MethodHandle is64BitMH =
                        MethodHandles.lookup()
                                .findVirtual(
                                        runtimeClass,
                                        "is64Bit",
                                        MethodType.methodType(boolean.class));
                return (boolean) is64BitMH.invoke(runtime);
            } catch (Throwable t) {
                throw new RuntimeException(t);
            }
        } else {
            return System.getProperty("sun.arch.data.model").equals("64");
        }
    }

    public static byte[] createFilledByteArray(int size) {
        byte[] array = new byte[size];
        for (int i = 0; i != size; ++i) {
            array[i] = (byte) (i * 47 + 11);
        }
        return array;
    }

    public static boolean getBytesAs_boolean(byte[] array, int index, ByteOrder order) {
        return getBytesAs_boolean(ByteBuffer.wrap(array), index, order);
    }

    public static byte getBytesAs_byte(byte[] array, int index, ByteOrder order) {
        return getBytesAs_byte(ByteBuffer.wrap(array), index, order);
    }

    public static char getBytesAs_char(byte[] array, int index, ByteOrder order) {
        return getBytesAs_char(ByteBuffer.wrap(array), index, order);
    }

    public static short getBytesAs_short(byte[] array, int index, ByteOrder order) {
        return getBytesAs_short(ByteBuffer.wrap(array), index, order);
    }

    public static int getBytesAs_int(byte[] array, int index, ByteOrder order) {
        return getBytesAs_int(ByteBuffer.wrap(array), index, order);
    }

    public static long getBytesAs_long(byte[] array, int index, ByteOrder order) {
        return getBytesAs_long(ByteBuffer.wrap(array), index, order);
    }

    public static float getBytesAs_float(byte[] array, int index, ByteOrder order) {
        return getBytesAs_float(ByteBuffer.wrap(array), index, order);
    }

    public static double getBytesAs_double(byte[] array, int index, ByteOrder order) {
        return getBytesAs_double(ByteBuffer.wrap(array), index, order);
    }

    public static boolean getBytesAs_boolean(ByteBuffer buffer, int index, ByteOrder order) {
        return buffer.order(order).get(index) != 0;
    }

    public static byte getBytesAs_byte(ByteBuffer buffer, int index, ByteOrder order) {
        return buffer.order(order).get(index);
    }

    public static char getBytesAs_char(ByteBuffer buffer, int index, ByteOrder order) {
        return buffer.order(order).getChar(index);
    }

    public static short getBytesAs_short(ByteBuffer buffer, int index, ByteOrder order) {
        return buffer.order(order).getShort(index);
    }

    public static int getBytesAs_int(ByteBuffer buffer, int index, ByteOrder order) {
        return buffer.order(order).getInt(index);
    }

    public static long getBytesAs_long(ByteBuffer buffer, int index, ByteOrder order) {
        return buffer.order(order).getLong(index);
    }

    public static float getBytesAs_float(ByteBuffer buffer, int index, ByteOrder order) {
        return buffer.order(order).getFloat(index);
    }

    public static double getBytesAs_double(ByteBuffer buffer, int index, ByteOrder order) {
        return buffer.order(order).getDouble(index);
    }

    public static void setBytesAs_boolean(byte[] array, int index, boolean value, ByteOrder order) {
        setBytesAs_boolean(ByteBuffer.wrap(array), index, value, order);
    }

    public static void setBytesAs_byte(byte[] array, int index, byte value, ByteOrder order) {
        setBytesAs_byte(ByteBuffer.wrap(array), index, value, order);
    }

    public static void setBytesAs_char(byte[] array, int index, char value, ByteOrder order) {
        setBytesAs_char(ByteBuffer.wrap(array), index, value, order);
    }

    public static void setBytesAs_short(byte[] array, int index, short value, ByteOrder order) {
        setBytesAs_short(ByteBuffer.wrap(array), index, value, order);
    }

    public static void setBytesAs_int(byte[] array, int index, int value, ByteOrder order) {
        setBytesAs_int(ByteBuffer.wrap(array), index, value, order);
    }

    public static void setBytesAs_long(byte[] array, int index, long value, ByteOrder order) {
        setBytesAs_long(ByteBuffer.wrap(array), index, value, order);
    }

    public static void setBytesAs_float(byte[] array, int index, float value, ByteOrder order) {
        setBytesAs_float(ByteBuffer.wrap(array), index, value, order);
    }

    public static void setBytesAs_double(byte[] array, int index, double value, ByteOrder order) {
        setBytesAs_double(ByteBuffer.wrap(array), index, value, order);
    }

    public static void setBytesAs_boolean(
            ByteBuffer buffer, int index, boolean value, ByteOrder order) {
        buffer.order(order).put(index, value ? (byte) 1 : (byte) 0);
    }

    public static void setBytesAs_byte(ByteBuffer buffer, int index, byte value, ByteOrder order) {
        buffer.order(order).put(index, value);
    }

    public static void setBytesAs_char(ByteBuffer buffer, int index, char value, ByteOrder order) {
        buffer.order(order).putChar(index, value);
    }

    public static void setBytesAs_short(
            ByteBuffer buffer, int index, short value, ByteOrder order) {
        buffer.order(order).putShort(index, value);
    }

    public static void setBytesAs_int(ByteBuffer buffer, int index, int value, ByteOrder order) {
        buffer.order(order).putInt(index, value);
    }

    public static void setBytesAs_long(ByteBuffer buffer, int index, long value, ByteOrder order) {
        buffer.order(order).putLong(index, value);
    }

    public static void setBytesAs_float(
            ByteBuffer buffer, int index, float value, ByteOrder order) {
        buffer.order(order).putFloat(index, value);
    }

    public static void setBytesAs_double(
            ByteBuffer buffer, int index, double value, ByteOrder order) {
        buffer.order(order).putDouble(index, value);
    }

    // Until ART is running on an OpenJDK9 based runtime, there are no
    // calls to help with alignment. OpenJDK9 introduces
    // ByteBuffer.alignedSlice() and ByteBuffer.alignmentOffset(). RI
    // and ART have different data structure alignments which may make
    // porting code interesting.

    public static int alignedOffset_char(ByteBuffer buffer, int start) {
        return alignedOffset_short(buffer, start);
    }

    public static int alignedOffset_short(ByteBuffer buffer, int start) {
        for (int i = 0; i < Short.SIZE; ++i) {
            try {
                vh_probe_short.getVolatile(buffer, start + i);
                return start + i;
            } catch (IllegalStateException e) {
                // Unaligned access.
            }
        }
        return start;
    }

    public static int alignedOffset_int(ByteBuffer buffer, int start) {
        for (int i = 0; i < Integer.SIZE; ++i) {
            try {
                vh_probe_int.getVolatile(buffer, start + i);
                return start + i;
            } catch (IllegalStateException e) {
                // Unaligned access.
            } catch (Exception e) {
                break;
            }
        }
        return start;
    }

    public static int alignedOffset_long(ByteBuffer buffer, int start) {
        for (int i = 0; i < Long.SIZE; ++i) {
            try {
                vh_probe_long.getVolatile(buffer, start + i);
                return start + i;
            } catch (IllegalStateException e) {
                // Unaligned access.
            } catch (UnsupportedOperationException e) {
                // 64-bit operation is not supported irrespective of alignment.
                break;
            }
        }
        return start;
    }

    public static int alignedOffset_float(ByteBuffer buffer, int start) {
        return alignedOffset_int(buffer, start);
    }

    public static int alignedOffset_double(ByteBuffer buffer, int start) {
        return alignedOffset_long(buffer, start);
    }

    public static int alignedOffset_char(byte[] array, int start) {
        return alignedOffset_char(ByteBuffer.wrap(array), start);
    }

    public static int alignedOffset_short(byte[] array, int start) {
        return alignedOffset_short(ByteBuffer.wrap(array), start);
    }

    public static int alignedOffset_int(byte[] array, int start) {
        return alignedOffset_int(ByteBuffer.wrap(array), start);
    }

    public static int alignedOffset_long(byte[] array, int start) {
        return alignedOffset_long(ByteBuffer.wrap(array), start);
    }

    public static int alignedOffset_float(byte[] array, int start) {
        return alignedOffset_float(ByteBuffer.wrap(array), start);
    }

    public static int alignedOffset_double(byte[] array, int start) {
        return alignedOffset_double(ByteBuffer.wrap(array), start);
    }

    static {
        ByteOrder order = ByteOrder.LITTLE_ENDIAN;
        vh_probe_short = MethodHandles.byteBufferViewVarHandle(short[].class, order);
        vh_probe_int = MethodHandles.byteBufferViewVarHandle(int[].class, order);
        vh_probe_long = MethodHandles.byteBufferViewVarHandle(long[].class, order);
    }

    private static final VarHandle vh_probe_short;
    private static final VarHandle vh_probe_int;
    private static final VarHandle vh_probe_long;
}
