using System;
using System.Collections.Generic;
using System.Text;

namespace RecrownedAthenaeum.Tools.CommandProcessor
{
    internal class CommandEngine
    {
        public bool running = true;
        public readonly List<EngineCommand> commands;

        public CommandEngine()
        {
            commands = new List<EngineCommand>();
        }

        internal void Run()
        {
            while (running)
            {
                ConsoleUtilities.WriteWrappedLine("\nAwaiting command.");
                string command = Console.ReadLine();
                try
                {
                    Process(command);

                }
                catch (ArgumentException ae)
                {
                    ConsoleUtilities.WriteWrappedLine("Error: " + ae.Message);
                }
            }
        }

        public void Process(string commandAndArguments)
        {
            string command = commandAndArguments;
            string[] arguments = null;

            if (commandAndArguments.Contains(' '))
            {
                command = command.Remove(command.IndexOf(' '));
                if (!ContainsCommand(command)) throw new ArgumentException("Command not found.");
                string[] argumentsSplit = commandAndArguments.Substring(command.Length + 1).Split(' ');
                List<string> argumentsList = new List<string>();

                for (int i = 0; i < argumentsSplit.Length; i++)
                {
                    if (argumentsSplit[i].Contains('"') && !argumentsSplit[i].EndsWith('"'))
                    {
                        StringBuilder quoteBuilder = new StringBuilder();
                        do
                        {
                            quoteBuilder.Append(' ');
                            quoteBuilder.Append(argumentsSplit[i]);
                            i++;
                            if (i >= argumentsSplit.Length)
                            {
                                throw new ArgumentException("Argument is missing terminating \'\"\'");
                            }

                        } while (!argumentsSplit[i].Contains('"'));
                        quoteBuilder.Append(' ');
                        quoteBuilder.Append(argumentsSplit[i]);
                        argumentsList.Add(quoteBuilder.ToString().Replace("\"", "").Trim());
                    }
                    else
                    {
                        argumentsList.Add(argumentsSplit[i]);
                    }
                }
                arguments = argumentsList.ToArray();
            }
            if (!ContainsCommand(command)) throw new ArgumentException("Command not found. Type \"help\" for a list of commands.");
            GetCommand(command).Run(arguments);
        }

        public bool ContainsCommand(string command)
        {
            for (int i = 0; i < commands.Count; i++)
            {
                if (commands[i].IsInvoked(command)) return true;
            }
            return false;
        }

        public EngineCommand GetCommand(string command)
        {
            for (int i = 0; i < commands.Count; i++)
            {
                if (commands[i].IsInvoked(command)) return commands[i];
            }

            return null;
        }
    }
}
