package openperipheral.adapter.composed;

import java.util.List;
import java.util.Map;
import java.util.Set;

import openperipheral.adapter.IDescriptable;
import openperipheral.adapter.IMethodExecutor;
import openperipheral.api.*;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Asynchronous
public class MethodsListerHelper {
	private final Map<String, IMethodExecutor> methods;
	private final Set<String> sources;

	public MethodsListerHelper(Map<String, IMethodExecutor> methods, Set<String> sources) {
		this.methods = methods;
		this.sources = sources;
	}

	@LuaCallable(returnTypes = LuaReturnType.STRING, description = "List all the methods available")
	public String listMethods(@Optionals @Arg(name = "namesOnly") Boolean namesOnly) {
		boolean justNames = namesOnly == Boolean.TRUE;
		List<String> info = Lists.newArrayList();
		for (Map.Entry<String, IMethodExecutor> e : methods.entrySet()) {
			final String name = e.getKey();

			if (justNames) {
				info.add(name);
			} else {
				final IDescriptable m = e.getValue().description();
				info.add(name + m.signature());
			}
		}
		return Joiner.on(", ").join(info);
	}

	@LuaCallable(returnTypes = LuaReturnType.TABLE, description = "List all method sources")
	public Map<String, Boolean> listSources() {
		Map<String, Boolean> result = Maps.newHashMap();
		for (String source : sources) {
			result.put(source, Boolean.TRUE);
		}
		return result;
	}

	@LuaCallable(returnTypes = LuaReturnType.STRING, description = "Brief description of method")
	public String doc(@Arg(name = "method") String methodName) {
		IMethodExecutor method = methods.get(methodName);
		Preconditions.checkArgument(method != null, "Method not found");
		return method.description().doc();
	}

	@LuaCallable(returnTypes = LuaReturnType.TABLE, description = "Get a complete table of information about all available methods")
	public Map<?, ?> getAdvancedMethodsData(@Optionals @Arg(name = "method") String methodName) {
		if (methodName != null) {
			IMethodExecutor method = methods.get(methodName);
			Preconditions.checkArgument(method != null, "Method not found");
			return method.description().describe();
		} else {
			Map<String, Object> info = Maps.newHashMap();
			for (Map.Entry<String, IMethodExecutor> e : methods.entrySet()) {
				final IDescriptable m = e.getValue().description();
				info.put(e.getKey(), m.describe());
			}
			return info;
		}
	}
}
@@ -825,89 +825,39 @@
  = %22
-namesOnly%22) Boolean namesOnly) %7B%0A%09%09boolean justNames = namesOnly == Boolean.TRUE;
+filterSource%22) String source) %7B
 %0A%09%09L
@@ -1004,62 +1004,59 @@
 ();%0A
-%0A
 %09%09%09
-if (justNames) %7B%0A%09%09%09%09info.add(name);%0A%09%09%09%7D else %7B%0A%09
+final IMethodExecutor executor = e.getValue();%0A%0A
 %09%09%09f
@@ -1075,35 +1075,31 @@
 ptable m = e
-.getValue()
+xecutor
 .description
@@ -1101,25 +1101,73 @@
 ption();%0A%09%09%09
-%09
+if (source == null %7C%7C source.equals(m.source())) 
 info.add(nam
@@ -1186,21 +1186,16 @@
 ure());%0A
-%09%09%09%7D%0A
 %09%09%7D%0A%09%09re

Change .listMethods() to filter by source