package com.tisawesomeness.minecord.command.misc;

import com.tisawesomeness.minecord.Bot;
import com.tisawesomeness.minecord.command.CommandContext;
import com.tisawesomeness.minecord.command.Result;
import com.tisawesomeness.minecord.util.DateUtils;

import lombok.NonNull;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.sharding.ShardManager;
import net.dv8tion.jda.api.utils.MarkdownUtil;

import java.text.CharacterIterator;
import java.text.StringCharacterIterator;

public class InfoCommand extends AbstractMiscCommand {

    private static final String JAVA_VERSION = System.getProperty("java.version");

    public @NonNull String getId() {
        return "info";
    }

    public Result run(String[] args, CommandContext ctx) {
        ShardManager sm = ctx.bot.getShardManager();

        // If the author used the admin keyword and is an elevated user
        boolean elevated = false;
        if (args.length > 0 && "admin".equals(args[0]) && ctx.isElevated) {
            elevated = true;
        }

        // Build message
        EmbedBuilder eb = new EmbedBuilder();

        eb.addField("Author", Bot.author, true);
        eb.addField("Version", Bot.version, true);

        String guilds = String.valueOf(sm.getGuilds().size());
        int shardTotal = ctx.bot.getShardManager().getShardsTotal();
        if (shardTotal > 1) {
            String shards = ctx.e.getJDA().getShardInfo().getShardId() + 1 + "/" + shardTotal;
            eb.addField("Shard", shards, true);
            guilds += " {" + ctx.e.getJDA().getGuilds().size() + "}";
        }
        eb.addField("Guilds", guilds, true);

        eb.addField("Uptime", DateUtils.getDurationString(ctx.bot.getBirth()), true);
        eb.addField("Ping", sm.getAverageGatewayPing() + "ms", true);
        if (ctx.config.getFlagConfig().isShowExtraInfo() || elevated) {
            eb.addField("Memory", getMemoryString(), true);
            eb.addField("Boot Time", DateUtils.getBootTime(ctx.bot.getBootTime()), true);
        }
        eb.addField("Java Version", MarkdownUtil.monospace(JAVA_VERSION), true);
        eb.addField("JDA Version", MarkdownUtil.monospace(Bot.jdaVersion), true);

        String links = MarkdownUtil.maskedLink("INVITE", ctx.config.getInviteLink()) + " | " +
            MarkdownUtil.maskedLink("SUPPORT", Bot.helpServer) + " | " +
            MarkdownUtil.maskedLink("WEBSITE", Bot.website) + " | " +
            MarkdownUtil.maskedLink("GITHUB", Bot.github);
        eb.addField("Links", "**" + links + "**", false);

        return ctx.reply(eb);
    }

    // Calculate memory
    // From https://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java/3758880#3758880
    private static String getMemoryString() {
        long bytes = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
        long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
        if (absB < 1024) {
            return bytes + " B";
        }
        long value = absB;
        CharacterIterator ci = new StringCharacterIterator("KMGTPE");
        for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10) {
            value >>= 10;
            ci.next();
        }
        value *= Long.signum(bytes);
        return String.format("%.1f %ciB", value / 1024.0, ci.current());
    }

}

@@ -625,16 +625,322 @@
 rsion%22);
+%0A    private static final String JAVA_VENDOR = System.getProperty(%22java.vendor%22);%0A    private static final String OS_ARCH = System.getProperty(%22os.arch%22);%0A    private static final String OS_NAME = System.getProperty(%22os.name%22);%0A    private static final String OS_VERSION = System.getProperty(%22os.version%22);
 %0A%0A    pu
@@ -1487,16 +1487,39 @@
 rsion%22, 
+MarkdownUtil.monospace(
 Bot.vers
@@ -1521,16 +1521,17 @@
 .version
+)
 , true);
@@ -2243,32 +2243,32 @@
 tring(), true);%0A
-
             eb.a
@@ -2333,32 +2333,269 @@
 Time()), true);%0A
+            eb.addField(%22OS%22, OS_NAME, true);%0A            eb.addField(%22OS Arch%22, OS_ARCH, true);%0A            eb.addField(%22OS Version%22, MarkdownUtil.monospace(OS_VERSION), true);%0A            eb.addField(%22Java Vendor%22, JAVA_VENDOR, true);%0A
         %7D%0A      

Add java vendor and OS info to extra &info