package org.frustra.feather;

import org.frustra.filament.injection.annotations.OverrideMethod;
import org.frustra.filament.injection.annotations.ProxyMethod;
import org.frustra.filament.injection.annotations.ReplaceSuperClass;

/**
 * The base class for every command. It gets dynamically rewritten to extend the
 * internal Minecraft command class, and proxies Minecraft's internal methods to
 * our own commands.
 */
@ReplaceSuperClass("HelpCommandClass.baseCommand")
public abstract class Command {
	@ReplaceSuperClass("HelpCommandClass.baseCommand")
	public Command() {}

	@OverrideMethod("GetCommandNameMethod.getName")
	private String getNameI() {
		return this.getName();
	}

	/**
	 * Gets the base name of the command, as it would be invoked by an entity.
	 * 
	 * @return the command's name
	 */
	public abstract String getName();

	/**
	 * Whether a particular entity has access to this command or not.
	 * 
	 * @param source the entity that invoked the command
	 * @return the accessibility of the command
	 */
	public abstract boolean hasPermission(Entity source);

	/**
	 * Called when a particular entity has invoked this command. Permissions
	 * will have already been checked.
	 * 
	 * @param source the entity that invoked the command
	 * @param arguments any arguments given by the player, split by spaces
	 */
	public abstract void execute(Entity source, String[] arguments);

	/**
	 * Executes a command string as the server.
	 * 
	 * @param command the command string
	 */
	public static void execute(String command) {
		execute(Feather.minecraftServer, command);
	}

	@ProxyMethod(
		classHook = "CommandManagerClass.commandManager",
		methodHook = "ExecuteCommandMethod.executeCommand"
	)
	private static native int executeI(Object instance, Object source, String command);

	/**
	 * Executes a command string as if it were run by a particular source
	 * entity.
	 * 
	 * @param source the proxied entity source
	 * @param command the command string
	 */
	public static void execute(Object source, String command) {
		executeI(Feather.commandManager, (Command) source, command);
	}

	/**
	 * Sends some text to the server log.
	 * 
	 * @param str the format string
	 * @param values the list of values to interpolate
	 */
	public static void log(String str, Object[] values) {
		respond(Feather.minecraftServer, str, values);
	}

	@ProxyMethod(
		classHook = "HelpCommandClass.baseCommand",
		methodHook = "SendClientMessageMethod.sendMessage"
	)
	private static native void respondI(Object target, String str, Object[] values);

	/**
	 * Sends some text to a particular target internal entity.
	 * 
	 * @param target the proxied entity target
	 * @param str the format string
	 * @param values the list of values to interpolate
	 */
	public static void respond(Object target, String str, Object[] values) {
		respondI(target, str, values);
	}
}

@@ -1589,35 +1589,32 @@
 %0A%0A%09@ProxyMethod(
-%0A%09%09
 classHook = %22Com
@@ -1646,19 +1646,17 @@
 anager%22,
-%0A%09%09
+ 
 methodHo
@@ -1697,18 +1697,16 @@
 Command%22
-%0A%09
 )%0A%09priva
@@ -1715,23 +1715,16 @@
  static 
-native 
 int exec
@@ -1775,17 +1775,33 @@
 command)
-;
+ %7B%0A%09%09return 0;%0A%09%7D
 %0A%0A%09/**%0A%09
@@ -2363,19 +2363,16 @@
 yMethod(
-%0A%09%09
 classHoo
@@ -2406,19 +2406,17 @@
 ommand%22,
-%0A%09%09
+ 
 methodHo
@@ -2457,18 +2457,16 @@
 Message%22
-%0A%09
 )%0A%09priva
@@ -2479,15 +2479,8 @@
 tic 
-native 
 void
@@ -2532,17 +2532,19 @@
  values)
-;
+ %7B%7D
 %0A%0A%09/**%0A%09

Remove native functions in Command