package dyvilx.tools.repl.command;

import dyvil.collection.Entry;
import dyvil.collection.Map;
import dyvil.collection.Set;
import dyvil.collection.mutable.HashMap;
import dyvil.collection.mutable.TreeMap;
import dyvil.collection.mutable.TreeSet;
import dyvilx.tools.repl.DyvilREPL;
import dyvilx.tools.repl.lang.I18n;

import java.io.PrintStream;

public class HelpCommand implements ICommand
{
	@Override
	public String getName()
	{
		return "help";
	}

	@Override
	public String getUsage()
	{
		return ":help [command]";
	}

	@Override
	public void execute(DyvilREPL repl, String argument)
	{
		if (argument == null)
		{
			this.printAllCommands(repl);
			return;
		}

		this.printCommandInfo(repl, argument);
	}

	private void printAllCommands(DyvilREPL repl)
	{
		final PrintStream output = repl.getOutput();
		output.println(I18n.get("command.help.available"));

		Map<ICommand, Set<String>> commands = new HashMap<>();

		for (Entry<String, ICommand> entry : DyvilREPL.getCommands())
		{
			final ICommand command = entry.getValue();
			Set<String> names = commands.get(command);
			if (names == null)
			{
				commands.put(command, names = new TreeSet<>());
			}
			names.add(entry.getKey());
		}

		Map<String, ICommand> result = new TreeMap<>();
		for (Entry<ICommand, Set<String>> entry : commands)
		{
			result.put(entry.getValue().toString("", ", ", ""), entry.getKey());
		}

		int maxLength = 0;
		for (String s : result.keys())
		{
			if (s.length() > maxLength)
			{
				maxLength = s.length();
			}
		}

		for (Entry<String, ICommand> entry : result)
		{
			output.printf("%1$" + maxLength + "s - %2$s\n", entry.getKey(), getDesc(entry.getValue().getName()));
		}
	}

	private void printCommandInfo(DyvilREPL repl, String commandName)
	{
		final ICommand command = DyvilREPL.getCommands().get(commandName);
		if (command == null)
		{
			repl.getErrorOutput().println(I18n.get("command.not_found", commandName));
			return;
		}

		final PrintStream output = repl.getOutput();

		output.println(I18n.get("command.help.header", command.getName(), getDesc(commandName)));
		output.println(I18n.get("command.help.usage", command.getUsage()));

		final String[] aliases = command.getAliases();
		if (aliases != null && aliases.length > 0)
		{
			output.println(I18n.get("command.help.aliases", String.join(", ", (CharSequence[]) aliases)));
		}
	}

	private static String getDesc(String commandName)
	{
		return I18n.get("command." + commandName + ".desc");
	}
}

@@ -88,122 +88,11 @@
 ion.
-Map;%0Aimport dyvil.collection.Set;%0Aimport dyvil.collection.mutable.HashMap;%0Aimport dyvil.collection.mutable.TreeMap
+Set
 ;%0Aim
@@ -758,21 +758,13 @@
 %0A%0A%09%09
-Map%3CICommand,
+final
  Set
@@ -771,17 +771,16 @@
 %3CString%3E
-%3E
  command
@@ -791,15 +791,15 @@
 new 
-HashMap
+TreeSet
 %3C%3E()
@@ -876,476 +876,162 @@
 %0A%09%09%09
-final ICommand command = entry.getValue();%0A%09%09%09Set%3CString%3E names = commands.get(command);%0A%09%09%09if (names == null)%0A%09%09%09%7B%0A%09%09%09%09commands.put(command, names = new TreeSet%3C%3E());%0A%09%09%09%7D%0A%09%09%09names.add(entry.getKey());%0A%09%09%7D%0A%0A%09%09Map%3CString, ICommand%3E result = new TreeMap%3C%3E();%0A%09%09for (Entry%3CICommand, Set%3CString%3E%3E entry : commands)%0A%09%09%7B%0A%09%09%09result.put(entry.getValue().toString(%22%22, %22, %22, %22%22), entry.getKey());%0A%09%09%7D%0A%0A%09%09int maxLength = 0;%0A%09%09for (String s : result.keys())
+commands.add(entry.getValue().getName());%0A%09%09%7D%0A%0A%09%09int maxLength = 0;%0A%0A%09%09for (String name : commands)%0A%09%09%7B%0A%09%09%09final int length = name.length();
 %0A%09
-%09%7B%0A
 %09%09
-%09
 if (
-s.
 length
-()
  %3E m
@@ -1065,18 +1065,14 @@
 h = 
-s.
 length
-()
 ;%0A%09%09
@@ -1086,77 +1086,35 @@
 %0A%09%09f
-or (Entry%3CString, ICommand%3E entry : result)%0A%09%09%7B%0A%09%09%09output.printf(%22
+inal String format = %22:
 %251$
+-
 %22 + 
@@ -1141,60 +1141,88 @@
 s%5Cn%22
-, entry.getKey(), getDesc(entry.getValue().getN
+;%0A%09%09for (String name : commands)%0A%09%09%7B%0A%09%09%09output.printf(format, name, getDesc(n
 ame
-()
 ));%0A
@@ -1410,28 +1410,22 @@
 .get
-ErrorOutput().printl
+Compiler().war
 n(I1
@@ -1864,25 +1864,8 @@
 , %22,
- (CharSequence%5B%5D)
  ali

Improve :help REP Command