package me.StevenLawson.TotalFreedomMod.httpd;

import me.StevenLawson.TotalFreedomMod.util.Utilities;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandMap;
import org.bukkit.command.PluginIdentifiableCommand;

import java.util.*;

import static me.StevenLawson.TotalFreedomMod.httpd.HTMLGenerationTools.heading;
import static me.StevenLawson.TotalFreedomMod.httpd.HTMLGenerationTools.paragraph;
import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;

public class HTTPDHelpModule extends HTTPDModule {
    public HTTPDHelpModule(NanoHTTPD.HTTPSession session) {
        super(session);
    }

    @Override
    public String getBody() {
        StringBuilder responseBody = new StringBuilder();

        CommandMap commandMap = Utilities.getField(Bukkit.getServer().getPluginManager(), "commandMap");
        HashMap<String, Command> knownCommands;
        if (commandMap == null
                || (knownCommands = Utilities.getField(commandMap, "knownCommands")) == null) {
            return paragraph("Error loading commands.");
        }

        responseBody
                .append(heading("Command Help", 1))
                .append(paragraph(
                        "This page is an automatically generated listing of all plugin commands that are currently live on the server. "
                                + "Please note that it does not include vanilla server commands."));

        final Map<String, List<Command>> commandsByPlugin = new HashMap<String, List<Command>>();

        final Iterator<Map.Entry<String, Command>> itKnownCommands = knownCommands.entrySet().iterator();
        while (itKnownCommands.hasNext())
        {
            final Map.Entry<String, Command> entry = itKnownCommands.next();
            final String name = entry.getKey();
            final Command command = entry.getValue();
            if (name.equalsIgnoreCase(command.getName()))
            {
                String pluginName = "Bukkit Default";
                if (command instanceof PluginIdentifiableCommand)
                {
                    pluginName = ((PluginIdentifiableCommand) command).getPlugin().getName();
                }
                List<Command> pluginCommands = commandsByPlugin.get(pluginName);
                if (pluginCommands == null)
                {
                    commandsByPlugin.put(pluginName, pluginCommands = new ArrayList<Command>());
                }
                pluginCommands.add(command);
            }
        }

        final Iterator<Map.Entry<String, List<Command>>> itCommandsByPlugin = commandsByPlugin.entrySet().iterator();
        while (itCommandsByPlugin.hasNext())
        {
            final Map.Entry<String, List<Command>> entry = itCommandsByPlugin.next();
            final String pluginName = entry.getKey();
            final List<Command> commands = entry.getValue();

            Collections.sort(commands, Comparator.comparing(Command::getName));

            responseBody.append(heading(pluginName, 2)).append("<ul>\r\n");

            for (Command command : commands)
            {
                responseBody.append(buildDescription(command));
            }

            responseBody.append("</ul>\r\n");
        }

        return responseBody.toString();
    }

    private static String buildDescription(Command command)
    {
        StringBuilder sb = new StringBuilder();

        sb.append(
                "<li><span class=\"commandName\">{$CMD_NAME}</span> - Usage: <span class=\"commandUsage\">{$CMD_USAGE}</span>"
                .replace("{$CMD_NAME}", escapeHtml4(command.getName().trim()))
                .replace("{$CMD_USAGE}", escapeHtml4(command.getUsage().trim())));

        if (!command.getAliases().isEmpty())
        {
            sb.append(
                    " - Aliases: <span class=\"commandAliases\">{$CMD_ALIASES}</span>"
                    .replace("{$CMD_ALIASES}", escapeHtml4(StringUtils.join(command.getAliases(), ", "))));
        }

        sb.append(
                "<br><span class=\"commandDescription\">{$CMD_DESC}</span></li>\r\n"
                .replace("{$CMD_DESC}", escapeHtml4(command.getDescription().trim())));

        return sb.toString();
    }

    @Override
    public String getTitle()
    {
        return "TotalFreedomMod :: Command Help";
    }

    @Override
    public String getStyle()
    {
        return ".commandName{font-weight:bold;}.commandDescription{padding-left:15px;}li{margin:.15em;padding:.15em;}";
    }
//    @Override
//    public String getScript()
//    {
//        return "$(document).ready(function(){console.log(\"Ready\");});";
//    }
}
