package net.knarcraft.serverlauncher;

import net.knarcraft.serverlauncher.profile.Collection;
import net.knarcraft.serverlauncher.profile.Profile;
import net.knarcraft.serverlauncher.server.Server;
import net.knarcraft.serverlauncher.server.ServerType;
import net.knarcraft.serverlauncher.userinterface.GUI;
import net.knarcraft.serverlauncher.userinterface.ServerConsoles;

import javax.naming.ConfigurationException;
import java.awt.*;
import java.io.*;
import java.net.URISyntaxException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static net.knarcraft.serverlauncher.Shared.stringBetween;
//Java 8 required.

/**
 * A software for managing Minecraft servers.
 *
 * @author		Kristian Knarvik <kristian.knarvik@knett.no>
 * @version	0.0.0.1
 * @since		0.0.0.1
 */

public class Main {
    @SuppressWarnings("CanBeFinal")
    public static String appDir;

    static {
        try {
            appDir = String.valueOf(new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile());
        } catch (URISyntaxException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static void main(String[] args) {
		EventQueue.invokeLater(() -> {
			try {
				setup();
				new ServerConsoles();
                Profile.load();

				ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
				exec.scheduleAtFixedRate(Main::updateConsoles, 10, 500, TimeUnit.MILLISECONDS);
			} catch (Exception e) {
				e.printStackTrace();
			}
		});
	}

	private static void setup() {
		try {
			ServerType.loadServerTypes();
		} catch (ConfigurationException e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

    /**
     * Reads from server processes, and writes the output to our custom consoles.
     */
	private static void updateConsoles() {
        for (Collection collection : Profile.getCurrent().getCollections()) {
            Server server = collection.getServer();
            if (server.isEnabled() && server.getProcess() != null) {
                try {
                    String readText = server.read();
                    if (!readText.equals("")) {
                        collection.getServerConsole().output(readText);
                        updatePlayerList(readText, server);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Looks for strings implying a player has joined or left, and updates the appropriate lists.
     *
     * @param text          The text to search.
     * @param server    The server which sent the text.
     */
	private static void updatePlayerList(String text, Server server) {
	    if (!server.getTypeName().equals("Bungee")) {
            String joinedPlayer = stringBetween(text, "[Server thread/INFO]: ", " joined the game");
            if (!joinedPlayer.equals("")) {
                if (!server.hasPlayer(joinedPlayer)) {
                    server.addPlayer(joinedPlayer);
                }
            } else {
                joinedPlayer = stringBetween(text, "UUID of player ", " is ");
                if (!joinedPlayer.equals("")) {
                    if (!server.hasPlayer(joinedPlayer)) {
                        server.addPlayer(joinedPlayer);
                    }
                }
            }
            if (joinedPlayer.equals("")) {
                String leftPlayer = stringBetween(text, "INFO]: ", " lost connection");
                if (!leftPlayer.equals("")) {
                    if (server.hasPlayer(leftPlayer)) {
                        server.removePlayer(leftPlayer);
                    }
                } else {
                    leftPlayer = stringBetween(text, "[Server thread/INFO]: ", " left the game");
                    if (!leftPlayer.equals("")) {
                        if (server.hasPlayer(leftPlayer)) {
                            server.removePlayer(leftPlayer);
                        }
                    }
                }
            }
        }
    }
}