package io.quarkus.vertx.core.runtime.graal;

import java.io.IOException;
import java.net.URL;
import java.util.function.Function;

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

@TargetClass(className = "URLClassPath$Loader", classNameProvider = Package_jdk_internal_loader.class)
final class Target_URLClassPath$Loader {

    @Alias
    public Target_URLClassPath$Loader(URL url) {
    }
}

@TargetClass(className = "URLClassPath$FileLoader", classNameProvider = Package_jdk_internal_loader.class)
final class Target_URLClassPath$FileLoader {

    @Alias
    public Target_URLClassPath$FileLoader(URL url) throws IOException {
    }
}

@TargetClass(className = "sun.misc.URLClassPath", onlyWith = JDK8OrEarlier.class)
final class Target_sun_misc_URLClassPath {

    @Substitute
    private Target_URLClassPath$Loader getLoader(final URL url) throws IOException {
        String file = url.getFile();
        if (file != null && file.endsWith("/")) {
            if ("file".equals(url.getProtocol())) {
                return (Target_URLClassPath$Loader) (Object) new Target_URLClassPath$FileLoader(
                        url);
            } else {
                return new Target_URLClassPath$Loader(url);
            }
        } else {
            // that must be wrong, but JarLoader is deleted by SVM
            return (Target_URLClassPath$Loader) (Object) new Target_URLClassPath$FileLoader(
                    url);
        }
    }

    @Substitute
    private int[] getLookupCache(String name) {
        return null;
    }
}

@TargetClass(className = "jdk.internal.loader.URLClassPath", onlyWith = JDK11OrLater.class)
final class Target_jdk_internal_loader_URLClassPath {

    @Substitute
    private Target_URLClassPath$Loader getLoader(final URL url) throws IOException {
        String file = url.getFile();
        if (file != null && file.endsWith("/")) {
            if ("file".equals(url.getProtocol())) {
                return (Target_URLClassPath$Loader) (Object) new Target_URLClassPath$FileLoader(
                        url);
            } else {
                return new Target_URLClassPath$Loader(url);
            }
        } else {
            // that must be wrong, but JarLoader is deleted by SVM
            return (Target_URLClassPath$Loader) (Object) new Target_URLClassPath$FileLoader(
                    url);
        }
    }

}

final class Package_jdk_internal_loader implements Function<TargetClass, String> {

    private static final JDK8OrEarlier JDK_8_OR_EARLIER = new JDK8OrEarlier();

    @Override
    public String apply(TargetClass annotation) {
        if (JDK_8_OR_EARLIER.getAsBoolean()) {
            return "sun.misc." + annotation.className();
        }

        return "jdk.internal.loader." + annotation.className();
    }
}

class JdkSubstitutions {

}

@@ -88,16 +88,74 @@
 et.URL;%0A
+import java.nio.channels.spi.AsynchronousChannelProvider;%0A
 import j
@@ -226,16 +226,69 @@
 .Alias;%0A
+import com.oracle.svm.core.annotate.InjectAccessors;%0A
 import c
@@ -3077,16 +3077,1210 @@
    %7D%0A%7D%0A%0A
+@Substitute%0A@TargetClass(className = %22sun.nio.ch.WindowsAsynchronousFileChannelImpl%22, innerClass = %22DefaultIocpHolder%22, onlyWith = JDK11OrLater.class)%0Afinal class Target_sun_nio_ch_WindowsAsynchronousFileChannelImpl_DefaultIocpHolder %7B%0A%0A    @Alias%0A    @InjectAccessors(DefaultIocpAccessor.class)%0A    static Target_sun_nio_ch_Iocp defaultIocp;%0A%7D%0A%0A@TargetClass(className = %22sun.nio.ch.Iocp%22, onlyWith = JDK11OrLater.class)%0Afinal class Target_sun_nio_ch_Iocp %7B%0A%0A    @Alias%0A    Target_sun_nio_ch_Iocp(AsynchronousChannelProvider provider, Target_sun_nio_ch_ThreadPool pool) throws IOException %7B%0A    %7D%0A%0A    @Alias%0A    Target_sun_nio_ch_Iocp start() %7B%0A        return null;%0A    %7D%0A%7D%0A%0A@TargetClass(className = %22sun.nio.ch.ThreadPool%22, onlyWith = JDK11OrLater.class)%0Afinal class Target_sun_nio_ch_ThreadPool %7B%0A%0A    @Alias%0A    static Target_sun_nio_ch_ThreadPool createDefault() %7B%0A        return null;%0A    %7D%0A%7D%0A%0Afinal class DefaultIocpAccessor %7B%0A    static Target_sun_nio_ch_Iocp get() %7B%0A        try %7B%0A            return new Target_sun_nio_ch_Iocp(null, Target_sun_nio_ch_ThreadPool.createDefault()).start();%0A        %7D catch (IOException ioe) %7B%0A            throw new InternalError(ioe);%0A        %7D%0A    %7D%0A%7D%0A%0A
 class Jd

Initialize sun.nio.ch.Iocp at runtime on Windows with JDK 11