package eu.nets.sis.idrights.demoapp.startup;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.BindException;
import java.net.InetAddress;
import java.net.ServerSocket;

import javax.net.ServerSocketFactory;
import javax.servlet.http.HttpServlet;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import eu.nets.sis.idrights.demoapp.DemoAppProperties;
import eu.nets.sis.idrights.demoapp.controller.ApplicationController;

public class ServerSetup {
private static final Logger LOGGER = LogManager.getLogger(ServerSetup.class);
	
	private static final String HOST = "localhost";
    private static final int PORT = DemoAppProperties.port;
    private static final String DOC_BASE = ".";
	
	public void start() throws IOException {
		Tomcat tomcat = createTomcatInstance();
		try {
			tomcat.start();
		} catch (LifecycleException exception) {
			System.out.println("Tomcat server startup failed. " + exception.getMessage());
			System.out.println("Exit...");
			System.exit(1);
		}

		LOGGER.info("Application has started with URL " + DemoAppProperties.baseUrl + DemoAppProperties.contextPath);
		printBanner();
		System.out.println("\n\nPlease point your preferred browser to " + DemoAppProperties.baseUrl + DemoAppProperties.contextPath);
		tomcat.getServer().await();
	}
	
	private Tomcat createTomcatInstance() {
		Tomcat tomcat = new Tomcat();
		tomcat.setPort(PORT);
        tomcat.setHostname(HOST);
        
        tomcat.getHost().setAppBase(DOC_BASE);
        Context context = tomcat.addWebapp("", DOC_BASE);
        tomcat.getConnector();
        
        setController(tomcat, context);

        return tomcat;
	}
	
	private void setController(Tomcat tomcat,  Context context) {
		HttpServlet httpServlet = new ApplicationController();
        String servletName = "demoapp_controller";
        tomcat.addServlet("", servletName, httpServlet);
        context.addServletMappingDecoded(DemoAppProperties.contextPath, servletName);
	}
	
	public static boolean isPortAvailable() throws IOException {
		try (ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(
				PORT, 1, InetAddress.getByName("localhost"))){			
			return true;
		} catch (BindException ex) {
			return false;
		}
	}
	
	private void printBanner() {
		ClassLoader classLoader = getClass().getClassLoader();
        InputStream inputStream = classLoader.getResourceAsStream("banner.txt");
        try(BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
            String line = br.readLine();

            while (line != null) {
            	System.out.println(line);
                line = br.readLine();
            }
        } catch (IOException e) {
			//Ignore
		}
	}
}
