package com.avairebot.orion.middleware;

import com.avairebot.orion.Orion;
import com.avairebot.orion.commands.CommandMessage;
import com.avairebot.orion.contracts.middleware.Middleware;
import net.dv8tion.jda.core.entities.Message;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ProcessCommand extends Middleware {

    private final static String COMMAND_OUTPUT = "Executing Command \"%command%\" in \"%category%\" category:"
        + "\n\t\tUser:\t %author%"
        + "\n\t\tServer:\t %server%"
        + "\n\t\tChannel: %channel%"
        + "\n\t\tMessage: %message%";

    private final Pattern argumentsRegEX;

    public ProcessCommand(Orion orion) {
        super(orion);

        this.argumentsRegEX = Pattern.compile("([^\"]\\S*|\".+?\")\\s*", Pattern.MULTILINE);
    }

    @Override
    public boolean handle(Message message, MiddlewareStack stack, String... args) {
        String[] arguments = generateCommandArguments(message);

        orion.logger.info(COMMAND_OUTPUT
            .replace("%command%", stack.getCommand().getName())
            .replace("%category%", stack.getCommandContainer().getCategory().getName())
            .replace("%author%", generateUsername(message))
            .replace("%server%", generateServer(message))
            .replace("%channel%", generateChannel(message))
            .replace("%message%", message.getRawContent())
        );

        return stack.getCommand().onCommand(
            new CommandMessage(message, stack.isMentionableCommand()),
            Arrays.copyOfRange(arguments, stack.isMentionableCommand() ? 2 : 1, arguments.length)
        );
    }

    private String[] generateCommandArguments(Message message) {
        List<String> arguments = new ArrayList<>();

        Matcher matcher = argumentsRegEX.matcher(message.getRawContent());
        while (matcher.find()) {
            arguments.add(matcher.group(0)
                .replaceAll("\"", "")
                .trim());
        }

        return arguments.toArray(new String[0]);
    }

    private String generateUsername(Message message) {
        return String.format("%s#%s [%s]",
            message.getAuthor().getName(),
            message.getAuthor().getDiscriminator(),
            message.getAuthor().getId()
        );
    }

    private String generateServer(Message message) {
        if (!message.getChannelType().isGuild()) {
            return "PRIVATE";
        }

        return String.format("%s [%s]",
            message.getGuild().getName(),
            message.getGuild().getId()
        );
    }

    private CharSequence generateChannel(Message message) {
        if (!message.getChannelType().isGuild()) {
            return "PRIVATE";
        }

        return String.format("%s [%s]",
            message.getChannel().getName(),
            message.getChannel().getId()
        );
    }
}

@@ -180,16 +180,134 @@
 leware;%0A
+import com.avairebot.orion.factories.MessageFactory;%0Aimport com.sedmelluq.discord.lavaplayer.tools.FriendlyException;%0A
 import n
@@ -417,24 +417,62 @@
 .util.List;%0A
+import java.util.concurrent.TimeUnit;%0A
 import java.
@@ -1641,24 +1641,42 @@
         );%0A%0A
+        try %7B%0A    
         retu
@@ -1708,16 +1708,20 @@
 ommand(%0A
+    
         
@@ -1795,16 +1795,20 @@
         
+  
+  
 Arrays.c
@@ -1885,34 +1885,382 @@
 length)%0A        
-);
+    );%0A        %7D catch (Exception ex) %7B%0A            if (ex instanceof FriendlyException) %7B%0A                MessageFactory.makeError(message, %22Error: %22 + ex.getMessage())%0A                    .queue(newMessage -%3E newMessage.delete().queueAfter(30, TimeUnit.SECONDS));%0A            %7D%0A%0A            ex.printStackTrace();%0A            return false;%0A        %7D
 %0A    %7D%0A%0A    priv

Add friendly try-catch statements in process command middleware