package net.bytebuddy.utility;

import net.bytebuddy.utility.privilege.GetSystemPropertyAction;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;

import java.security.AccessController;

/**
 * A {@link ClassReader} that does not apply a class file version check if the {@code net.bytebuddy.experimental} property is set.
 */
public class OpenedClassReader {

    /**
     * Indicates that Byte Buddy should not validate the maximum supported class file version.
     */
    public static final String EXPERIMENTAL_PROPERTY = "net.bytebuddy.experimental";

    /**
     * {@code true} if Byte Buddy is executed in experimental mode.
     */
    public static final boolean EXPERIMENTAL;

    /**
     * Indicates the ASM API version that is used throughout Byte Buddy.
     */
    public static final int ASM_API;

    /*
     * Checks the experimental property.
     */
    static {
        boolean experimental;
        int asmApi;
        try {
            experimental = Boolean.parseBoolean(AccessController.doPrivileged(new GetSystemPropertyAction(EXPERIMENTAL_PROPERTY)));
            @SuppressWarnings("deprecation")
            int asm7Experimental = Opcodes.ASM7_EXPERIMENTAL;
            asmApi = experimental ? asm7Experimental : Opcodes.ASM6;
        } catch (Exception ignored) {
            experimental = false;
            asmApi = Opcodes.ASM6;
        }
        EXPERIMENTAL = experimental;
        ASM_API = asmApi;
    }

    /**
     * Not intended for construction.
     */
    private OpenedClassReader() {
        throw new UnsupportedOperationException("This class is a utility class and not supposed to be instantiated");
    }

    /**
     * Creates a class reader for the given binary representation of a class file.
     *
     * @param binaryRepresentation The binary representation of a class file to read.
     * @return An appropriate class reader.
     */
    public static ClassReader of(byte[] binaryRepresentation) {
        if (EXPERIMENTAL) {
            byte[] actualVersion = new byte[]{binaryRepresentation[4], binaryRepresentation[5], binaryRepresentation[6], binaryRepresentation[7]};
            binaryRepresentation[4] = (byte) (Opcodes.V10 >>> 24);
            binaryRepresentation[5] = (byte) (Opcodes.V10 >>> 16);
            binaryRepresentation[6] = (byte) (Opcodes.V10 >>> 8);
            binaryRepresentation[7] = (byte) Opcodes.V10;
            ClassReader classReader = new ClassReader(binaryRepresentation);
            System.arraycopy(actualVersion, 0, binaryRepresentation, 4, actualVersion.length);
            return classReader;
        } else {
            return new ClassReader(binaryRepresentation);
        }
    }
}

@@ -933,28 +933,8 @@
 al;%0A
-        int asmApi;%0A
     
@@ -943,16 +943,16 @@
   try %7B%0A
+
         
@@ -1079,184 +1079,8 @@
 ));%0A
-            @SuppressWarnings(%22deprecation%22)%0A            int asm7Experimental = Opcodes.ASM7_EXPERIMENTAL;%0A            asmApi = experimental ? asm7Experimental : Opcodes.ASM6;%0A
     
@@ -1151,43 +1151,8 @@
 se;%0A
-            asmApi = Opcodes.ASM6;%0A
     
@@ -1206,24 +1206,163 @@
     
-ASM_API = asmApi
+@SuppressWarnings(%22deprecation%22)%0A        int asm7Experimental = Opcodes.ASM7_EXPERIMENTAL;%0A        ASM_API = experimental ? asm7Experimental : Opcodes.ASM6
 ;%0A  

Simplify code.