//   Copyright 2012 Georg-August-Universität Göttingen, Germany
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

package de.ugoe.cs.autoquest.httpmonitor;

import javax.servlet.Servlet;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

import de.ugoe.cs.util.console.Console;

/**
 * <p>
 * this is the web server, that is used either for the monitor or the proxy. It is initialized with
 * a port and the servlet to be deployed. It implements the {@link HttpMonitorComponent} to be
 * simply initialized, started, and stopped. 
 * </p>
 * 
 * @author Patrick Harms
 */
public class HttpMonitorServer implements HttpMonitorComponent {

    /**
     * the port to listen on
     */
    private int port;

    /**
     * the jetty web server used for receiving messages
     */
    private Server server;

    /**
     * the message listener to forward the messages to
     */
    private Servlet servlet;

    /**
     * <p>
     * initializes the server with the port to listen on and the servlet to be deployed.
     * </p>
     *
     * @param port    the port to listen on
     * @param servlet the servlet to be deployed
     */
    public HttpMonitorServer(int port, Servlet servlet) {
        this.port = port;
        this.servlet = servlet;
    }

    /* (non-Javadoc)
     * @see de.ugoe.cs.autoquest.htmlmonitor.HttpMonitorComponent#init()
     */
    @Override
    public synchronized void init() {
        if (server != null) {
            throw new IllegalStateException("already initialized. First call stop()");
        }

        server = new Server(port);
        
        /*
        // the following code can be used to support SSL directly
        server = new Server();
        
        SslSocketConnector connector = new SslSocketConnector();
        connector.setPort(port);
        connector.setKeystore("data/keystore");
        connector.setPassword("123456");
        connector.setKeyPassword("123456");
        connector.setTruststore("data/keystore");
        connector.setTrustPassword("123456");
        server.addConnector(connector);*/

        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        server.setHandler(context);
 
        context.addServlet(new ServletHolder(servlet), "/*");
    }

    /* (non-Javadoc)
     * @see de.ugoe.cs.autoquest.htmlmonitor.HttpMonitorComponent#start()
     */
    @Override
    public synchronized void start() throws HttpMonitorException {
        if (server == null) {
            throw new IllegalStateException("server not initialized yet. First call init()");
        }
        
        try {
            server.start();
        }
        catch (Exception e) {
            throw new HttpMonitorException("could not start server", e);
        }
    }


    /* (non-Javadoc)
     * @see de.ugoe.cs.autoquest.htmlmonitor.HttpMonitorComponent#stop()
     */
    @Override
    public synchronized void stop() {
        try {
            if (server != null) {
                server.stop();
            }
        }
        catch (Exception e) {
            Console.printerrln("could not stop server: " + e.getMessage());
            Console.logException(e);
        }
    }

}
