package com.digistratum.microhost;

import com.digistratum.microhost.Controller.Controller;
import com.digistratum.microhost.Exception.MHException;
import com.sun.net.httpserver.HttpServer;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;

public class Server {
	HttpServer server;
	Map<String, Controller> controllerMap;

	/**
	 * Configuration-injected constructor
	 *
	 * @param config
	 * @throws IOException
	 */
	public Server(Config config) throws IOException {
		this(
				Integer.parseInt(config.get("port","54321")),
				Integer.parseInt(config.get("threads","10"))
		);
	}

	/**
	 * Parametric constructor
	 *
	 * @param port Listening port for our MicroHost HTTP service
	 * @param threadPoolSize Count of threads for our pool (concurrency limit)
	 *
	 * @throws IOException
	 */
	public Server(int port, int threadPoolSize) throws IOException {
		server = HttpServer.create(new InetSocketAddress(port), 0);

		// ref: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool(int)
		server.setExecutor(Executors.newFixedThreadPool(threadPoolSize));

		controllerMap = new HashMap<>();

		// Start the MicroHost HttpServer; Note that we can still add/remove
		// controller contexts on-the-fly while the server is running
		server.start();
	}

	/**
	 * Add a controller context to this server
	 *
	 * A controller is responsible for all request URIs relative to the context path
	 *
	 * @param ctrl Controller instance to do the work
	 * @param ctx String context base URI to map this controller to
	 *
	 * @throws MHException
	 */
	public void addControllerContext(Controller ctrl, String ctx) throws MHException {
		if ((null == ctrl) || (null == ctx) || ctx.isEmpty()) {
			throw new MHException("Attempted to add invalid controller context for: '" + ctx + "'");
		}
		controllerMap.put(ctx, ctrl);
		server.createContext(ctx, ctrl);
	}

	/**
	 * Server stopper
	 */
	public void stop() {
		server.stop(0);
	}
}

@@ -1764,16 +1764,64 @@
 eption %7B
+%0A%0A%09%09// If the controller or context are bogus...
 %0A%09%09if ((
@@ -1937,19 +1937,234 @@
 ler 
+for 
 context
- for
+: '%22 + ctx + %22'%22);%0A%09%09%7D%0A%0A%09%09// If the context is already defined, it must be removed before we attempt to replace it%0A%09%09if (hasContext(ctx)) %7B%0A%09%09%09throw new MHException(%22Attempted to add duplicate controller for context
 : '%22
@@ -2181,16 +2181,30 @@
 '%22);%0A%09%09%7D
+%0A%0A%09%09// Add it!
 %0A%09%09contr
@@ -2263,24 +2263,817 @@
  ctrl);%0A%09%7D%0A%0A
+%09/**%0A%09 * Remove a context which is already defined%0A%09 *%0A%09 * @param ctx String context base URI to which this controller is mapped%0A%09 *%0A%09 * @throws MHException%0A%09 */%0A%09public void removeContext(String ctx) throws MHException %7B%0A%09%09if (! hasContext(ctx)) %7B%0A%09%09%09throw new MHException(%22Attempted to remove undefined context: '%22 + ctx + %22'%22);%0A%09%09%7D%0A%09%09server.removeContext(ctx);%0A%09%09controllerMap.remove(ctx);%0A%09%7D%0A%0A%09/**%0A%09 * Check whether the specified context is already defined%0A%09 *%0A%09 * Note that this does not evaluate the URI to see if some other less specific context maps to this...%0A%09 *%0A%09 * @param ctx String context base URI which we want to check%0A%09 *%0A%09 * @return boolean true if the context is defined, else false%0A%09 */%0A%09public boolean hasContext(String ctx) %7B%0A%09%09return controllerMap.containsKey(ctx);%0A%09%7D%0A%0A
 %09/**%0A%09 * Ser

Add a couple context helper methods