package eu.dnetlib.test;

import java.io.File;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.ContextHandlerCollection;
import org.mortbay.jetty.handler.DefaultHandler;
import org.mortbay.jetty.handler.HandlerCollection;
import org.mortbay.jetty.plus.webapp.EnvConfiguration;
import org.mortbay.jetty.webapp.Configuration;
import org.mortbay.jetty.webapp.WebAppContext;
import org.mortbay.jetty.webapp.WebXmlConfiguration;
import org.mortbay.resource.Resource;

import eu.dnetlib.enabling.is.store.TestContentInitializerJob;

/**
 * Manages the standalone container.
 * 
 * @author marko
 * 
 */
public class SimpleContainerManager {

	/**
	 * default jetty port.
	 */
	private static final int JETTY_PORT = 8090;

	/**
	 * wait for the webapp context to shut down.
	 */
	private static final long SHUTDOWN_TIMEOUT = 500L;

	/**
	 * Container initialization needs some time.
	 */
	private static final int INIT_TIME = 30000;

	/**
	 * Perhaps the container is ready before the INIT_TIME: poll it.
	 */
	private static final int INIT_TIME_TICK = 200;

	/**
	 * logger.
	 */
	private static final Log log = LogFactory.getLog(SimpleContainerManager.class); 

	/**
	 * jetty web app context.
	 */
	private transient WebAppContext context;
	/**
	 * jetty embedded server.
	 */
	private transient Server server;
	/**
	 * jetty embedded temporary directory.
	 */
	private transient File tmpDir;

	/**
	 * path to the directory containing the container webapp directory, containing
	 * web.xml and basic spring container context files. By default it uses the cnr-container directory
	 * which includes all cnr services.
	 */
	private String webapp;
	
	/**
	 * jetty port.
	 */
	private int jettyPort = JETTY_PORT;

	/**
	 * start the container.
	 */

	public void startContainer() {
		log.debug("prepare jetty");

		try {
			tmpDir = File.createTempFile("dnetJetty", "");
			tmpDir.delete();
			tmpDir.mkdir();

			server = new Server(getJettyPort());

			server.setStopAtShutdown(true);
			Resource.setDefaultUseCaches(false);

			ContextHandlerCollection contexts = (ContextHandlerCollection) server.getChildHandlerByClass(ContextHandlerCollection.class);

			if (contexts == null) {
				contexts = new ContextHandlerCollection();
				final HandlerCollection handlers = new HandlerCollection();
				server.setHandler(handlers);
				handlers.setHandlers(new Handler[] { contexts, new DefaultHandler() });
			}

			context = new WebAppContext(contexts, getWebapp(), "/app");
			context.setDisplayName("DNet");

			context.setConfigurations(new Configuration[] { new EnvConfiguration(), new WebXmlConfiguration() });
			context.setTempDirectory(tmpDir);
			context.setServer(server);

			TestContentInitializerJob.setInitialized(false);
			
			server.start();

			context.setShutdown(false);
			context.start();

			for (int i = 0; i < INIT_TIME / INIT_TIME_TICK; i++) {
				if (TestContentInitializerJob.isInitialized())
					break;
				Thread.sleep(INIT_TIME_TICK);
			}

		} catch (Exception e) {
			throw new IllegalStateException(e);
		}
	}

	/**
	 * stop container.
	 * 
	 * @throws Exception
	 *             happens
	 * 
	 */
	public void stopContainer() throws Exception { 
		context.setShutdown(true);
		Thread.sleep(SHUTDOWN_TIMEOUT);

		context.stop();
		server.stop();

		FileUtils.deleteDirectory(tmpDir);
	}

	public void setWebapp(final String webapp) {
		this.webapp = webapp;
	}

	public String getWebapp() {
		return webapp;
	}

	public void setJettyPort(final int jettyPort) {
		this.jettyPort = jettyPort;
	}

	public int getJettyPort() {
		return jettyPort;
	}
}
