package io.papermc.paper.util;

import io.papermc.paper.plugin.entrypoint.classloader.PaperPluginClassLoader;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.PluginClassLoader;
import org.jetbrains.annotations.Nullable;

import java.util.Objects;
import java.util.Optional;

public class StackWalkerUtil {

    @Nullable
    public static JavaPlugin getFirstPluginCaller() {
        Optional<JavaPlugin> foundFrame = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
            .walk(stream -> stream
                .map((frame) -> {
                    ClassLoader classLoader =  frame.getDeclaringClass().getClassLoader();
                    JavaPlugin plugin;
                    if (classLoader instanceof PaperPluginClassLoader pluginClassLoader) {
                        plugin = pluginClassLoader.getLoadedJavaPlugin();
                    } else if (classLoader instanceof PluginClassLoader spigotClassloader) {
                        plugin = spigotClassloader.getPlugin();
                    } else {
                        plugin = null;
                    }

                    return plugin;
                })
                .filter(Objects::nonNull)
                .findFirst());

        return foundFrame.orElse(null);
    }
}
