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

package com.hypixel.hytale.plugin.early;

import java.util.Collections;
import java.nio.file.DirectoryStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.util.Iterator;
import java.util.Comparator;
import java.util.ServiceLoader;
import java.net.URL;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import javax.annotation.Nullable;
import java.net.URLClassLoader;
import java.util.List;
import javax.annotation.Nonnull;
import java.nio.file.Path;

public final class EarlyPluginLoader
{
    @Nonnull
    public static final Path EARLY_PLUGINS_PATH;
    @Nonnull
    private static final List<ClassTransformer> transformers;
    @Nullable
    private static URLClassLoader pluginClassLoader;
    
    private EarlyPluginLoader() {
    }
    
    public static void loadEarlyPlugins(@Nonnull final String[] args) {
        final ObjectArrayList<URL> urls = new ObjectArrayList<URL>();
        collectPluginJars(EarlyPluginLoader.EARLY_PLUGINS_PATH, urls);
        for (final Path path : parseEarlyPluginPaths(args)) {
            collectPluginJars(path, urls);
        }
        if (urls.isEmpty()) {
            return;
        }
        EarlyPluginLoader.pluginClassLoader = new URLClassLoader(urls.toArray(URL[]::new), EarlyPluginLoader.class.getClassLoader());
        for (ClassTransformer transformer : ServiceLoader.load(ClassTransformer.class, EarlyPluginLoader.pluginClassLoader)) {
            System.out.println("[EarlyPlugin] Loading transformer: " + transformer.getClass().getName() + " (priority=" + transformer.priority());
            EarlyPluginLoader.transformers.add(transformer);
        }
        EarlyPluginLoader.transformers.sort(Comparator.comparingInt(ClassTransformer::priority).reversed());
        if (!EarlyPluginLoader.transformers.isEmpty()) {
            System.err.printf("""
                              ===============================================================================================
                                                            Loaded %d class transformer(s)!!
                              ===============================================================================================
                                                     This is unsupported and may cause stability issues.
                                                                   Use at your own risk!!
                              ===============================================================================================
                              """, EarlyPluginLoader.transformers.size());
            final boolean isSingleplayer = hasFlag(args, "--singleplayer");
            final boolean acceptEarlyPlugins = hasFlag(args, "--accept-early-plugins");
            if (!isSingleplayer && !acceptEarlyPlugins) {
                if (System.console() == null) {
                    System.err.println("ERROR: Early plugins require interactive confirmation, but no console is available.");
                    System.err.println("Pass --accept-early-plugins to accept the risk and continue.");
                    System.exit(1);
                }
                System.err.print("Press ENTER to accept and continue...");
                System.console().readLine();
            }
        }
    }
    
    private static List<Path> parseEarlyPluginPaths(@Nonnull final String[] args) {
        final ObjectArrayList<Path> paths = new ObjectArrayList<Path>();
        for (int i = 0; i < args.length; ++i) {
            if (args[i].equals("--early-plugins") && i + 1 < args.length) {
                for (final String pathStr : args[i + 1].split(",")) {
                    paths.add(Path.of(pathStr.trim(), new String[0]));
                }
            }
            else if (args[i].startsWith("--early-plugins=")) {
                final String value = args[i].substring("--early-plugins=".length());
                for (final String pathStr2 : value.split(",")) {
                    paths.add(Path.of(pathStr2.trim(), new String[0]));
                }
            }
        }
        return paths;
    }
    
    private static boolean hasFlag(final String[] args, final String flag) {
        for (final String arg : args) {
            if (arg.equals(flag)) {
                return true;
            }
        }
        return false;
    }
    
    private static void collectPluginJars(final Path path, final List<URL> urls) {
        if (!Files.isDirectory(path, new LinkOption[0])) {
            return;
        }
        try {
            final DirectoryStream<Path> stream = Files.newDirectoryStream(path, "*.jar");
            try {
                for (Path file : stream) {
                    if (Files.isRegularFile(file, new LinkOption[0])) {
                        urls.add(file.toUri().toURL());
                        System.out.println("[EarlyPlugin] Found: " + String.valueOf(file.getFileName()));
                    }
                }
                if (stream != null) {
                    stream.close();
                }
            }
            catch (final Throwable t) {
                if (stream != null) {
                    try {
                        stream.close();
                    }
                    catch (final Throwable exception) {
                        t.addSuppressed(exception);
                    }
                }
                throw t;
            }
        }
        catch (final IOException e) {
            System.err.println("[EarlyPlugin] Failed to scan directory " + String.valueOf(path) + ": " + e.getMessage());
        }
    }
    
    public static boolean hasTransformers() {
        return !EarlyPluginLoader.transformers.isEmpty();
    }
    
    public static List<ClassTransformer> getTransformers() {
        return Collections.unmodifiableList((List<? extends ClassTransformer>)EarlyPluginLoader.transformers);
    }
    
    @Nullable
    public static URLClassLoader getPluginClassLoader() {
        return EarlyPluginLoader.pluginClassLoader;
    }
    
    static {
        EARLY_PLUGINS_PATH = Path.of("earlyplugins", new String[0]);
        transformers = new ObjectArrayList<ClassTransformer>();
    }
}
