package io.github.Cnly.Crafter.Crafter.utils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandMap;
import org.bukkit.command.PluginCommand;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.SimplePluginManager;

public class CommandUtils
{
    
    private CommandUtils()
    {
        throw new AssertionError("This is a util class");
    }
    
    public static PluginCommand newPluginCommand(String name, Plugin plugin)
    {
        
        Constructor<PluginCommand> constructor = null;
        try
        {
            constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
        }
        catch(NoSuchMethodException | SecurityException e)
        {
            throw new RuntimeException("Error occurred while getting constructor from PluginCommand", e);
        }
        
        boolean accessible = constructor.isAccessible();
        constructor.setAccessible(true);
        
        PluginCommand pc = null;
        try
        {
            pc = constructor.newInstance(name, plugin);
        }
        catch(InstantiationException | IllegalAccessException | InvocationTargetException e)
        {
            throw new RuntimeException("Error occurred while creating new instance of PluginCommand", e);
        }
        finally
        {
            constructor.setAccessible(accessible);
        }
        
        return pc;
    }
    
    public static CommandMap getCommandMap()
    {
        
        PluginManager pm = Bukkit.getPluginManager();
        if(!(pm instanceof SimplePluginManager))
        {
            throw new RuntimeException("Plugin manager is not SimplePluginManager!");
        }
        
        pm = (SimplePluginManager)pm;
        
        Field commandMapField = null;
        try
        {
            commandMapField = SimplePluginManager.class.getDeclaredField("commandMap");
        }
        catch(NoSuchFieldException | SecurityException e)
        {
            throw new RuntimeException("Error occurred while getting field commandMap from SimplePluginManager", e);
        }
        
        boolean accessible = commandMapField.isAccessible();
        commandMapField.setAccessible(true);
        
        try
        {
            return (CommandMap)commandMapField.get(pm);
        }
        catch(IllegalArgumentException | IllegalAccessException e)
        {
            throw new RuntimeException("Error occurred while getting command map from SimplePluginManager", e);
        }
        finally
        {
            commandMapField.setAccessible(accessible);
        }
        
    }
    
    public static boolean register(String fallbackPrefix, Command command)
    {
        return getCommandMap().register(fallbackPrefix, command);
    }
    
    public static boolean register(Plugin plugin, Command command)
    {
        return register(plugin.getDescription().getName(), command);
    }
    
    public static boolean register(Plugin plugin, String commandName, CommandExecutor executor, String usage, String description, String permission, String... aliases)
    {
        
        PluginCommand pc = newPluginCommand(commandName, plugin);
        
        pc.setExecutor(executor);
        if(usage != null)
            pc.setUsage(usage);
        if(description != null)
            pc.setDescription(description);
        if(permission != null)
            pc.setPermission(permission);
        if(aliases != null)
            pc.setAliases(Arrays.asList(aliases));
        
        return register(plugin, pc);
    }
    
    public static boolean register(Plugin plugin, String commandName, CommandExecutor executor, String... aliases)
    {
        return register(plugin, commandName, executor, null, null, null, aliases);
    }
    
}

@@ -191,149 +191,55 @@
 ys;%0A
-%0A
 import 
-org.bukkit.Bukkit;%0Aimport org.bukkit.command.Command;%0Aimport org.bukkit.command.CommandExecutor;%0Aimport org.bukkit.command.CommandMap
+java.util.Map;%0A%0Aimport org.bukkit.Bukkit
 ;%0Aim
@@ -262,29 +262,17 @@
 command.
-PluginCommand
+*
 ;%0Aimport
@@ -3915,20 +3915,1502 @@
 ases);%0A    %7D
+%0A%0A    /**%0A     * Unregisters a command registered in SimpleCommandMap. Remember to also unregister your commands with fallbackPrefix added.%3Cbr /%3E%0A     * E.g. %3Cb%3EMyplugin:mycommand%3C/b%3E and %3Cb%3Emycommand%3C/b%3E%0A     * @param key The key in the knownCommands map.%0A     */%0A    public static void unregister(String key)%0A    %7B%0A%0A        CommandMap cm = getCommandMap();%0A        if(!(cm instanceof SimpleCommandMap))%0A        %7B%0A            throw new RuntimeException(%22CommandMap is not SimpleCommandMap!%22);%0A        %7D%0A%0A        cm = (SimpleCommandMap)cm;%0A%0A        Field knownCommandsField = null;%0A        try%0A        %7B%0A            knownCommandsField = SimpleCommandMap.class.getDeclaredField(%22knownCommands%22);%0A        %7D%0A        catch(NoSuchFieldException %7C SecurityException e)%0A        %7B%0A            throw new RuntimeException(%22Error occurred while getting field knownCommands from SimpleCommandMap%22, e);%0A        %7D%0A%0A        boolean accessible = knownCommandsField.isAccessible();%0A        knownCommandsField.setAccessible(true);%0A%0A        Map%3CString, Command%3E knownCommands = null;%0A        try%0A        %7B%0A            knownCommands = (Map%3CString, Command%3E)knownCommandsField.get(cm);%0A        %7D%0A        catch(IllegalAccessException e)%0A        %7B%0A            throw new RuntimeException(%22Error occurred while getting knownCommands from SimpleCommandMap%22, e);%0A        %7D%0A        finally%0A        %7B%0A            knownCommandsField.setAccessible(accessible);%0A        %7D%0A%0A        knownCommands.remove(key);%0A%0A    %7D
 %0A    %0A%7D%0A

Add unregister for CommandUtils