package com.supaham.commons.bukkit.commands.utils;
import com.google.common.base.Preconditions;
import com.sk89q.intake.Command;
import com.sk89q.intake.Require;
import com.supaham.commons.bukkit.commands.CommonCommandsManager;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nonnull;
/**
* Represents data for creating a custom Intake command.
*/
public class CommonCommandData {
private final CommonCommandsManager manager;
private final Object classInstance;
private final Method method;
private final List<String> aliases;
private final List<String> permissions;
public static Builder builder() {
return new Builder();
}
private CommonCommandData(CommonCommandsManager manager, Object classInstance, Method method, List<String> aliases,
List<String> permissions) {
this.manager = manager;
this.classInstance = classInstance;
this.method = method;
if (aliases != null) {
this.aliases = aliases;
} else {
this.aliases = Arrays.asList(method.getDeclaredAnnotation(Command.class).aliases());
}
if (permissions != null) {
this.permissions = permissions;
} else if (method.isAnnotationPresent(Require.class)) {
this.permissions = Arrays.asList(method.getDeclaredAnnotation(Require.class).value());
} else {
this.permissions = null;
}
}
public CommonCommandsManager getManager() {
return manager;
}
public Object getClassInstance() {
return classInstance;
}
public Method getMethod() {
return method;
}
public List<String> getAliases() {
return this.aliases;
}
public String[] getAliasesArray() {
return this.aliases.toArray(new String[this.aliases.size()]);
}
public List<String> getPermissions() {
return permissions;
}
public static final class Builder {
private CommonCommandsManager manager;
private Object classInstance;
private Method method;
private List<String> aliases;
private List<String> permissions;
public Builder manager(CommonCommandsManager manager) {
this.manager = manager;
return this;
}
public Builder classIntance(Object object) {
this.classInstance = object;
return this;
}
public Builder method(Method method) {
this.method = method;
return this;
}
public Builder methodName(@Nonnull String name) {
Preconditions.checkNotNull(name, "name cannot be null.");
boolean found = false;
Method method = null;
for (Method method1 : classInstance.getClass().getDeclaredMethods()) {
if (method1.getName().equals(name)) {
found = true;
Preconditions.checkState(method == null,
"There are multiple methods of the name %s. Please use method(Method).",
name);
if (method1.isAnnotationPresent(Command.class)) {
method = method1;
}
}
}
// Debug some helpful messages.
if (method == null) {
if (found) {
throw new IllegalStateException("Found method called " + name + " but it is not annotated with @Command.");
} else {
throw new IllegalStateException("No method exists in " + classInstance.getClass().getName()
+ " called " + name + ".");
}
}
return method(method);
}
public List<String> aliases() {
return this.aliases;
}
public Builder aliases(List<String> aliases) {
this.aliases = aliases;
return this;
}
public List<String> permissions() {
return this.permissions;
}
public Builder permissions(List<String> permissions) {
this.permissions = permissions;
return this;
}
public CommonCommandData build() {
Preconditions.checkNotNull(manager, "manager cannot be null.");
Preconditions.checkNotNull(classInstance, "classInstance cannot be null.");
if (aliases == null || permissions == null) {
if (aliases == null && permissions == null) {
throw new NullPointerException("Aliases or permissions must be set.");
}
}
Method method = this.method;
if (method == null) {
for (Method method1 : this.classInstance.getClass().getDeclaredMethods()) {
if (method1.isAnnotationPresent(Command.class)) {
Preconditions.checkArgument(method == null,
this.classInstance.getClass().getName() + " has two command methods. Please "
+ "specify which method");
method = method1;
}
}
}
Preconditions.checkNotNull(method, "No command method has been set or found.");
Command definition = method.getAnnotation(Command.class);
Preconditions.checkNotNull(definition, "Method lacks a @Command annotation");
return new CommonCommandData(manager, classInstance, method, aliases, permissions);
}
public void register() {
manager.registerMethod(this);
}
public void register(CommonCommandsManager manager) {
manager(manager).register();
}
}
}