using System;
using System.Text;
using SlatedGameToolkit.Tools.CommandSystem;
using SlatedGameToolkit.Tools.CommandSystem.Interaction;

namespace SlatedGameToolkit.Tools.Commands
{
    public class HelpCommand : IInvocable
    {
        private readonly string[] invokers = new string[] {"help"};
        private CommandMap commandMap;

        public HelpCommand(CommandMap commandMap) {
            this.commandMap = commandMap;
        }

        public bool Execute(IInteractable interactable, string[] args)
        {
            if (args.Length > 0) {
                IInvocable invocable = commandMap[args[0]];
                if (invocable == null) interactable.Tell("Unable to find command {0}. Please type \"help\" for more a list of commands.");
                StringBuilder builder = new StringBuilder();
                builder.AppendJoin(", ", invocable.GetInvokers());
                interactable.Tell("Possible aliases: " + builder.ToString());
                interactable.Tell("Description: " + invocable.getDescription());
                interactable.Tell("Usage: " + invocable.getUsage(args.Length > 0 ? args[0] : null));
            } else {
                interactable.Tell("--- Help ---");
                foreach (IInvocable invocable in commandMap)
                {
                    interactable.Separate();
                    StringBuilder builder = new StringBuilder();
                    builder.AppendJoin(", ", invocable.GetInvokers());
                    interactable.Tell(builder.ToString() + ": ");
                    interactable.Tell(invocable.getDescription());
                }
            }
            return true;
        }

        public string getDescription()
        {
            return "Displays the help message. You're looking at it.";
        }

        public string getUsage(string arg)
        {
            return "Usage: \"help [command]\" where [command] is a specific command you want to see usage for.";
        }

        public string[] GetInvokers()
        {
            return invokers;
        }

        public void Dispose()
        {
            
        }
    }
}