package com.tisawesomeness.minecord.command.misc;

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

import com.tisawesomeness.minecord.Bot;
import com.tisawesomeness.minecord.Config;
import com.tisawesomeness.minecord.command.Command;
import com.tisawesomeness.minecord.database.Database;
import com.tisawesomeness.minecord.util.DateUtils;
import com.tisawesomeness.minecord.util.DiscordUtils;
import com.tisawesomeness.minecord.util.MessageUtils;

import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.utils.MarkdownUtil;

public class InfoCommand extends Command {
	
	public CommandInfo getInfo() {
		return new CommandInfo(
			"info",
			"Shows the bot info.",
			null,
			new String[]{"about", "stats"},
			0,
			false,
			false,
			true
		);
	}

	public String getAdminHelp() {
		return "`{&}info` - Shows the bot info.\n" +
			"`{&}info admin` - Includes memory usage and boot time.\n";
	}
	
	public Result run(String[] args, MessageReceivedEvent e) {
		DiscordUtils.update();
		
		// If the author used the admin keyword and is an elevated user
		boolean elevated = false;
		if (args.length > 0 && args[0].equals("admin") && Database.isElevated(e.getAuthor().getIdLong())) {
			elevated = true;
		}
		
		// Build message
		EmbedBuilder eb = new EmbedBuilder();
		
		eb.setColor(Bot.color);
		eb.addField("Author", Bot.authorTag, true);
		eb.addField("Version", Bot.getVersion(), true);
		
		String guilds = Bot.shardManager.getGuilds().size() + "";
		if (Config.getShardCount() > 1) {
			String shards = e.getJDA().getShardInfo().getShardId() + 1 + "/" + Config.getShardCount();
			eb.addField("Shard", shards, true);
			guilds += " {" + e.getJDA().getGuilds().size() + "}";
		}
		eb.addField("Guilds", guilds + "", true);
		
		eb.addField("Uptime", DateUtils.getUptime(), true);
		eb.addField("Ping", Bot.shardManager.getAverageGatewayPing() + "ms", true);
		if (Config.getShowMemory() || elevated) {
			eb.addField("Memory", getMemoryString(), true);
			eb.addField("Boot Time", DateUtils.getBootTime(), true);
		}
		
		eb.addField("Library", String.format("Java `%s`, JDA `%s`", Bot.javaVersion, Bot.jdaVersion), true);
		eb.addField("Contribute", MarkdownUtil.maskedLink("Contribute on GitHub", Bot.github), true);
		eb.addField("Invite", Config.getInvite(), false);
		eb.addField("Help Server", Bot.helpServer, false);
		eb.addField("Website", Bot.website, false);
		
		eb = MessageUtils.addFooter(eb);
		return new Result(Outcome.SUCCESS, eb.build());
	}

	// Calculate memory
	// From https://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java/3758880#3758880
	public 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());
	}
	
}

@@ -960,17 +960,16 @@
  Include
-s
  memory 
@@ -993,16 +993,16 @@
 me.%5Cn%22;%0A
+
 %09%7D%0A%09%0A%09pu
@@ -1435,11 +1435,8 @@
 thor
-Tag
 , tr
@@ -2121,19 +2121,16 @@
 e);%0A%09%09%7D%0A
-%09%09%0A
 %09%09eb.add
@@ -2140,78 +2140,53 @@
 ld(%22
-Library%22, String.format(%22Java %60%25s%60, JDA %60%25s%60%22, Bot.java
+Java 
 Version
+%22
 , 
+MarkdownUtil.monospace(
 Bot.j
-d
+av
 aVer
@@ -2214,26 +2214,27 @@
 dField(%22
-Contribute
+JDA Version
 %22, Markd
@@ -2246,52 +2246,31 @@
 il.m
-askedLink(%22Contribute on GitHub%22, Bot.github
+onospace(Bot.jdaVersion
 ), t
@@ -2279,149 +2279,307 @@
 e);%0A
+%0A
 %09%09
-eb.addField(%22Invite%22, Config.getInvite(), false);%0A%09%09eb.addField(%22Help Server%22, Bot.helpServer, false);%0A%09%09eb.addField(%22Website%22, Bot.website
+String links = MarkdownUtil.maskedLink(%22INVITE%22, Config.getInvite()) + %22 %7C %22 +%0A%09%09%09MarkdownUtil.maskedLink(%22SUPPORT%22, Bot.helpServer) + %22 %7C %22 +%0A%09%09%09MarkdownUtil.maskedLink(%22WEBSITE%22, Bot.website) + %22 %7C %22 +%0A%09%09%09MarkdownUtil.maskedLink(%22GITHUB%22, Bot.github);%0A%09%09eb.addField(%22Links%22, %22**%22 + links + %22**%22
 , fa

Add links to &info