package com.github.bleuzen.blizcord;

import java.awt.Desktop;
import java.io.File;
import java.net.URI;
import java.util.concurrent.TimeUnit;

import com.github.bleuzen.blizcord.bot.Bot;
import com.github.bleuzen.blizcord.gui.GUI_Main;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;

import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Role;
import net.dv8tion.jda.core.entities.User;

public class Utils {

	private static String OS;

	public static String getOS() {
		if(OS != null) {
			return OS;
		}

		String tmp = System.getProperty("os.name").toLowerCase();
		if(tmp.equals(Values.OS_LINUX)) {
			return (OS = Values.OS_LINUX);
		} else if(tmp.startsWith(Values.OS_WINDOWS)) {
			return (OS = Values.OS_WINDOWS);
		} else {
			return (OS = Values.UNKNOWN_OS);
		}
	}

	public static boolean isUnknownOS() {
		return getOS().equals(Values.UNKNOWN_OS);
	}

	public static long timeToMS(int hours, int minutes, int seconds) {
		if(seconds > 59 || seconds < 0) {
			return -1;
		}
		if(minutes > 59 || minutes < 0) {
			return -1;
		}

		long s = (seconds + (60 * (minutes + (hours * 60))));
		return TimeUnit.SECONDS.toMillis(s);
	}

	public static String durationToTimeString(long duration) {
		TimeUnit scale = TimeUnit.MILLISECONDS;
		long days = scale.toDays(duration);
		duration -= TimeUnit.DAYS.toMillis(days);
		long hours = scale.toHours(duration);
		duration -= TimeUnit.HOURS.toMillis(hours);
		long minutes = scale.toMinutes(duration);
		duration -= TimeUnit.MINUTES.toMillis(minutes);
		long seconds = scale.toSeconds(duration);
		return String.format("%d days, %d hours, %d minutes, %d seconds", days, hours, minutes, seconds);
	}

	public static String getTrackName(AudioTrack track) {
		String sourceName = track.getSourceManager().getSourceName();
		if(sourceName.equals("local")) {
			return new File(track.getInfo().uri).getName();
		} else if(sourceName.equals("http")) {
			return track.getIdentifier();
		} else {
			return track.getInfo().title;
		}
	}

	public static boolean isAdmin(User user) {
		Guild guild = Bot.getGuild();
		Role adminRole = Bot.getAdminRole();
		return user.getId().equals(guild.getOwner().getUser().getId()) || (adminRole != null && guild.getMember(user).getRoles().contains(adminRole));
	}

	public static void openInBrowser(String link) {
		try {
			Desktop.getDesktop().browse(new URI(link));
		} catch (Exception e) {
			GUI_Main.showErrMsgBox(e.getMessage());
			errExit();
		}
	}

	static void errExit() {
		errExit(null);
	}

	public static void errExit(String msg) {
		errExit(msg, 1);
	}

	public static void errExit(String msg, int exitCode) {
		if(a.isGui()) {
			GUI_Main.onErrExit(msg);
		} else {
			Log.error("Crash! Reason:");
			System.err.println(msg == null ? "Unknown" : msg);
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				//e.printStackTrace();
			}
		}

		if(exitCode >= 1 && exitCode <= 127) {
			System.exit(exitCode);
		} else {
			System.exit(0);
		}
	}

	public static void handleError(String m) {
		Utils.errExit(m);
	}

	// "NCG" = "Not Crash GUI"
	// this is the same as handleError(m) but does not crash if GUI
	public static void handleErrorNCG(String m) {
		if(a.isGui()) {
			// Only show Error message box, but don't exit
			GUI_Main.showErrMsgBox(m);
		} else {
			// If not using GUI -> The old way: crash
			//TODO: double checks if a.isGui() (again in errExit()), Write better method?
			Utils.errExit(m);
		}
	}

	public static void handleException(Exception e) {
		if(a.isDebug()) {
			e.printStackTrace();
		}

		handleError(e.getMessage());
	}

	// "NCG" = "Not Crash GUI"
	public static void handleExceptionNCG(Exception e) {
		if(a.isDebug()) {
			e.printStackTrace();
		}

		handleErrorNCG(e.getMessage());
	}

	public static void printException(Exception e) {
		if(a.isDebug()) {
			e.printStackTrace();
		}
	}


	public static class ArgumentUtils {

		public static int getArgIndex(String[] args, String arg) {
			int ir = -1; // return -1 if args does not contain the argument
			for(int in = 0; in < args.length; in++) {
				if(args[in].equalsIgnoreCase(arg)) {
					ir = in;
					break;
				}
			}
			return ir;
		}

		public static boolean containsArg(String[] args, String arg) {
			return getArgIndex(args, arg) != -1;
		}

		// returns the value behind an argument or null
		public static String getArg(String[] args, String arg) {
			int i = getArgIndex(args, arg);
			if(i != -1) {
				try {
					String result = args[i + 1];

					if(!result.startsWith("--")) {
						return result;
					}
				} catch(ArrayIndexOutOfBoundsException e) {
					Log.debug("Invalid argument value: {}", arg);
				}
			}

			return null;
		}

	}


}

@@ -287,16 +287,78 @@
 ioTrack;
+%0Aimport com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo;
 %0A%0Aimport
@@ -1897,24 +1897,252 @@
 %22local%22)) %7B%0A
+%09%09%09AudioTrackInfo info = track.getInfo();%0A%09%09%09String author = info.author;%0A%09%09%09String title = info.title;%0A%09%09%09if(!author.equals(%22Unknown artist%22) && !title.equals(%22Unknown title%22)) %7B%0A%09%09%09%09return author + %22 - %22 + title;%0A%09%09%09%7D else %7B%0A%09
 %09%09%09return ne
@@ -2176,24 +2176,29 @@
 .getName();%0A
+%09%09%09%7D%0A
 %09%09%7D else if(

use metadata from music file if possible