package io.quarkus.runtime.graal;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;

import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.jdk.JDK11OrLater;

/*
 * The `hasClassPath()` method substitution from this class is required to work around a NPE when `BootLoader.hasClassPath()`
 * is called. This was fixed in a GraalVM commit (https://github.com/oracle/graal/commit/68027de) which will be backported to
 * 19.3.1. We copied the entire GraalVM commit content into Quarkus for the sake of consistency.
 * See https://github.com/oracle/graal/issues/1966 for more details about the NPE.
 */
@TargetClass(className = "jdk.internal.loader.BootLoader", onlyWith = JDK11OrLater.class)
final class Target_jdk_internal_loader_BootLoader {

    @Substitute
    private static boolean hasClassPath() {
        return true;
    }

    @Substitute
    private static URL findResource(String mn, String name) {
        return ClassLoader.getSystemClassLoader().getResource(name);
    }

    @Substitute
    private static InputStream findResourceAsStream(String mn, String name) {
        return ClassLoader.getSystemClassLoader().getResourceAsStream(name);
    }

    @Substitute
    private static URL findResource(String name) {
        return ClassLoader.getSystemClassLoader().getResource(name);
    }

    @Substitute
    private static Enumeration<URL> findResources(String name) throws IOException {
        return ClassLoader.getSystemClassLoader().getResources(name);
    }
}

@@ -264,89 +264,822 @@
 ore.
-jdk.JDK11OrLater;%0A%0A/*%0A * The %60hasClassPath()%60 method substitution from this class
+hub.ClassForNameSupport;%0Aimport com.oracle.svm.core.jdk.JDK11OrLater;%0A%0A@TargetClass(className = %22jdk.internal.loader.BootLoader%22, onlyWith = JDK11OrLater.class)%0Afinal class Target_jdk_internal_loader_BootLoader %7B%0A%0A    /*%0A     * The following substitution is required to work around a NPE that happened when %60BootLoader.loadClassOrNull(name)%60 was%0A     * called during the Quarkus native integration tests execution. It will be directly fixed in a future GraalVM release%0A     * which is undetermined for now. This substitution should be removed as soon as Quarkus depends on a GraalVM version that%0A     * includes the fix.%0A     */%0A    @Substitute%0A    private static Class%3C?%3E loadClassOrNull(String name) %7B%0A        return ClassForNameSupport.forNameOrNull(name, false);%0A    %7D%0A%0A    /*%0A     * The following substitution
  is 
@@ -1108,16 +1108,30 @@
 d a NPE 
+that happened 
 when %60Bo
@@ -1158,21 +1158,19 @@
 h()%60
-%0A * i
+ wa
 s called
 . Th
@@ -1169,448 +1169,410 @@
 lled
-. This was fixed in a GraalVM commit (https://github.com/oracle/graal/commit/68027de) which will be backported to%0A * 19.3.1. We copied the entire GraalVM commit content into Quarkus for the sake of consistency.%0A * See https://github.com/oracle/graal/issues/1966 for more details about the NPE.%0A */%0A@TargetClass(className = %22jdk.internal.loader.BootLoader%22, onlyWith = JDK11OrLater.class)%0Afinal class Target_jdk_internal_loader_BootLoader %7B%0A
+%0A     * during the Quarkus native integration tests execution. It was fixed in a GraalVM commit which should be backported to%0A     * 19.3.1 (https://github.com/oracle/graal/commit/68027de). This substitution should be removed as soon as Quarkus depends%0A     * on a GraalVM version that includes that commit.%0A     * See https://github.com/oracle/graal/issues/1966 for more details about the NPE.%0A     */
 %0A   

Substitute BootLoader.loadClassOrNull(name) to fix a NPE with JDK 11