package com.cardshifter.server.model;

import java.util.Map;
import java.util.function.Consumer;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import com.cardshifter.server.clients.ClientIO;
import com.cardshifter.server.incoming.LoginMessage;
import com.cardshifter.server.incoming.StartGameRequest;
import com.cardshifter.server.main.FakeAIClientTCG;

public class MainServer {
	private static final Logger logger = LogManager.getLogger(MainServer.class);
	
	public void start() {
		try {
			logger.info("Starting Server...");
			Server server = new Server();
			
			server.addConnections(new ServerSock(server, 4242));
			server.addConnections(new ServerWeb(server, 4243));
			
			logger.info("Starting Console...");
			ServerConsole console = new ServerConsole(server, new CommandHandler());
			new Thread(console, "Console-Thread").start();
			console.addHandler("threads", cmd -> showAllStackTraces(server, System.out::println));
			logger.info("Started");
			
			// Setup an AI that automatically wants to play (for testing purposes)
			ClientIO tcgAI = new FakeAIClientTCG(server);
			server.newClient(tcgAI);
			server.getIncomingHandler().perform(new LoginMessage("AI Simple"), tcgAI);
			server.getIncomingHandler().perform(new StartGameRequest(), tcgAI);
		}
		catch (Exception e) {
			logger.error("Initializing Error", e);
		}
	}
	
	private void showAllStackTraces(Server server, Consumer<String> output) {
		output.accept("All stack traces:");
		Map<Thread, StackTraceElement[]> allTraces = Thread.getAllStackTraces();
		for (Thread thread : allTraces.keySet()) {
			output.accept(thread.getName());
			this.stackTrace(thread, output);
		}
	}
	
	private void stackTrace(Thread thread, Consumer<String> output) {
		StackTraceElement[] stackTrace = thread.getStackTrace();
		output.accept("Stack trace for thread " + thread.getId() + ": " + thread.getName());
		for (StackTraceElement trace : stackTrace) {
			output.accept(trace.toString());
		}
		output.accept("");
	}
	
}

@@ -733,24 +733,146 @@
 nsole...%22);%0A
+%09%09%09CommandHandler commandHandler = new CommandHandler();%0A%09%09%09commandHandler.addHandler(%22exit%22, command -%3E System.exit(0));%0A
 %09%09%09ServerCon
@@ -912,21 +912,17 @@
 server, 
-new C
+c
 ommandHa
@@ -926,18 +926,16 @@
 dHandler
-()
 );%0A%09%09%09ne

Exit command to shut down the server (the hard way)