// 
// Decompiled by Procyon v0.6.0
// 

package io.netty.util.internal;

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

final class VarHandleFactory
{
    private static final MethodHandle FIND_VAR_HANDLE;
    private static final MethodHandle PRIVATE_LOOKUP_IN;
    private static final VarHandle LONG_LE_ARRAY_VIEW;
    private static final VarHandle LONG_BE_ARRAY_VIEW;
    private static final VarHandle INT_LE_ARRAY_VIEW;
    private static final VarHandle INT_BE_ARRAY_VIEW;
    private static final VarHandle SHORT_LE_ARRAY_VIEW;
    private static final VarHandle SHORT_BE_ARRAY_VIEW;
    private static final VarHandle LONG_LE_BYTE_BUFFER_VIEW;
    private static final VarHandle LONG_BE_BYTE_BUFFER_VIEW;
    private static final VarHandle INT_LE_BYTE_BUFFER_VIEW;
    private static final VarHandle INT_BE_BYTE_BUFFER_VIEW;
    private static final VarHandle SHORT_LE_BYTE_BUFFER_VIEW;
    private static final VarHandle SHORT_BE_BYTE_BUFFER_VIEW;
    private static final Throwable UNAVAILABILITY_CAUSE;
    
    private VarHandleFactory() {
    }
    
    public static boolean isSupported() {
        return VarHandleFactory.UNAVAILABILITY_CAUSE == null;
    }
    
    public static Throwable unavailableCause() {
        return VarHandleFactory.UNAVAILABILITY_CAUSE;
    }
    
    private static MethodHandles.Lookup privateLookup(final MethodHandles.Lookup lookup, final Class<?> targetClass) {
        try {
            return VarHandleFactory.PRIVATE_LOOKUP_IN.invokeExact((Class)targetClass, lookup);
        }
        catch (final Throwable e) {
            throw new RuntimeException(e);
        }
    }
    
    public static VarHandle privateFindVarHandle(final MethodHandles.Lookup lookup, final Class<?> declaringClass, final String name, final Class<?> type) {
        try {
            return VarHandleFactory.FIND_VAR_HANDLE.invokeExact(privateLookup(lookup, declaringClass), (Class)declaringClass, name, (Class)type);
        }
        catch (final Throwable e) {
            throw new RuntimeException(e);
        }
    }
    
    public static VarHandle longLeArrayView() {
        return VarHandleFactory.LONG_LE_ARRAY_VIEW;
    }
    
    public static VarHandle longBeArrayView() {
        return VarHandleFactory.LONG_BE_ARRAY_VIEW;
    }
    
    public static VarHandle intLeArrayView() {
        return VarHandleFactory.INT_LE_ARRAY_VIEW;
    }
    
    public static VarHandle intBeArrayView() {
        return VarHandleFactory.INT_BE_ARRAY_VIEW;
    }
    
    public static VarHandle shortLeArrayView() {
        return VarHandleFactory.SHORT_LE_ARRAY_VIEW;
    }
    
    public static VarHandle shortBeArrayView() {
        return VarHandleFactory.SHORT_BE_ARRAY_VIEW;
    }
    
    public static VarHandle longLeByteBufferView() {
        return VarHandleFactory.LONG_LE_BYTE_BUFFER_VIEW;
    }
    
    public static VarHandle longBeByteBufferView() {
        return VarHandleFactory.LONG_BE_BYTE_BUFFER_VIEW;
    }
    
    public static VarHandle intLeByteBufferView() {
        return VarHandleFactory.INT_LE_BYTE_BUFFER_VIEW;
    }
    
    public static VarHandle intBeByteBufferView() {
        return VarHandleFactory.INT_BE_BYTE_BUFFER_VIEW;
    }
    
    public static VarHandle shortLeByteBufferView() {
        return VarHandleFactory.SHORT_LE_BYTE_BUFFER_VIEW;
    }
    
    public static VarHandle shortBeByteBufferView() {
        return VarHandleFactory.SHORT_BE_BYTE_BUFFER_VIEW;
    }
    
    static {
        MethodHandle findVarHandle = null;
        MethodHandle privateLookupIn = null;
        VarHandle longLeArrayViewHandle = null;
        VarHandle longBeArrayViewHandle = null;
        VarHandle intLeArrayViewHandle = null;
        VarHandle intBeArrayViewHandle = null;
        VarHandle shortLeArrayViewHandle = null;
        VarHandle shortBeArrayViewHandle = null;
        VarHandle longLeByteBufferViewHandle = null;
        VarHandle longBeByteBufferViewHandle = null;
        VarHandle intLeByteBufferViewHandle = null;
        VarHandle intBeByteBufferViewHandle = null;
        VarHandle shortLeByteBufferViewHandle = null;
        VarHandle shortBeByteBufferViewHandle = null;
        Throwable error = null;
        try {
            final MethodHandles.Lookup lookup = MethodHandles.lookup();
            findVarHandle = lookup.findVirtual(MethodHandles.Lookup.class, "findVarHandle", MethodType.methodType(VarHandle.class, Class.class, String.class, Class.class));
            privateLookupIn = lookup.findStatic(MethodHandles.class, "privateLookupIn", MethodType.methodType(MethodHandles.Lookup.class, Class.class, MethodHandles.Lookup.class));
            final MethodHandle byteArrayViewHandle = lookup.findStatic(MethodHandles.class, "byteArrayViewVarHandle", MethodType.methodType(VarHandle.class, Class.class, ByteOrder.class));
            longLeArrayViewHandle = byteArrayViewHandle.invokeExact((Class)long[].class, ByteOrder.LITTLE_ENDIAN);
            longBeArrayViewHandle = byteArrayViewHandle.invokeExact((Class)long[].class, ByteOrder.BIG_ENDIAN);
            intLeArrayViewHandle = byteArrayViewHandle.invokeExact((Class)int[].class, ByteOrder.LITTLE_ENDIAN);
            intBeArrayViewHandle = byteArrayViewHandle.invokeExact((Class)int[].class, ByteOrder.BIG_ENDIAN);
            shortLeArrayViewHandle = byteArrayViewHandle.invokeExact((Class)short[].class, ByteOrder.LITTLE_ENDIAN);
            shortBeArrayViewHandle = byteArrayViewHandle.invokeExact((Class)short[].class, ByteOrder.BIG_ENDIAN);
            final MethodHandle byteBufferViewHandle = lookup.findStatic(MethodHandles.class, "byteBufferViewVarHandle", MethodType.methodType(VarHandle.class, Class.class, ByteOrder.class));
            longLeByteBufferViewHandle = byteBufferViewHandle.invokeExact((Class)long[].class, ByteOrder.LITTLE_ENDIAN);
            longBeByteBufferViewHandle = byteBufferViewHandle.invokeExact((Class)long[].class, ByteOrder.BIG_ENDIAN);
            intLeByteBufferViewHandle = byteBufferViewHandle.invokeExact((Class)int[].class, ByteOrder.LITTLE_ENDIAN);
            intBeByteBufferViewHandle = byteBufferViewHandle.invokeExact((Class)int[].class, ByteOrder.BIG_ENDIAN);
            shortLeByteBufferViewHandle = byteBufferViewHandle.invokeExact((Class)short[].class, ByteOrder.LITTLE_ENDIAN);
            shortBeByteBufferViewHandle = byteBufferViewHandle.invokeExact((Class)short[].class, ByteOrder.BIG_ENDIAN);
            error = null;
        }
        catch (final Throwable e) {
            error = e;
            findVarHandle = null;
            privateLookupIn = null;
            longLeArrayViewHandle = null;
            longBeArrayViewHandle = null;
            intLeArrayViewHandle = null;
            intBeArrayViewHandle = null;
            shortLeArrayViewHandle = null;
            longLeByteBufferViewHandle = null;
            longBeByteBufferViewHandle = null;
            intLeByteBufferViewHandle = null;
            intBeByteBufferViewHandle = null;
            shortLeByteBufferViewHandle = null;
            shortBeByteBufferViewHandle = null;
        }
        finally {
            FIND_VAR_HANDLE = findVarHandle;
            PRIVATE_LOOKUP_IN = privateLookupIn;
            LONG_LE_ARRAY_VIEW = longLeArrayViewHandle;
            LONG_BE_ARRAY_VIEW = longBeArrayViewHandle;
            INT_LE_ARRAY_VIEW = intLeArrayViewHandle;
            INT_BE_ARRAY_VIEW = intBeArrayViewHandle;
            SHORT_LE_ARRAY_VIEW = shortLeArrayViewHandle;
            SHORT_BE_ARRAY_VIEW = shortBeArrayViewHandle;
            LONG_LE_BYTE_BUFFER_VIEW = longLeByteBufferViewHandle;
            LONG_BE_BYTE_BUFFER_VIEW = longBeByteBufferViewHandle;
            INT_LE_BYTE_BUFFER_VIEW = intLeByteBufferViewHandle;
            INT_BE_BYTE_BUFFER_VIEW = intBeByteBufferViewHandle;
            SHORT_LE_BYTE_BUFFER_VIEW = shortLeByteBufferViewHandle;
            SHORT_BE_BYTE_BUFFER_VIEW = shortBeByteBufferViewHandle;
            UNAVAILABILITY_CAUSE = error;
        }
    }
}
