package code;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.security.KeyStore;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.TrustManagerFactory;

import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsParameters;
import com.sun.net.httpserver.HttpsServer;

public class Server {

    public static int port = 443;
    public static final String VERSION = "1.0";

    public static void main(String[] args) throws IOException {
        if (args.length > 1 && args[0].equals("-port"))
            try {
                port = Integer.parseInt(args[1]);
            } catch (Exception e) {
                e.printStackTrace();
            }
        HttpsServer server = HttpsServer.create(new InetSocketAddress(port), 0);


        // initialise the HTTPS server
        try {
            SSLContext sslContext = SSLContext.getInstance("TLS");

            // initialise the keystore
            char[] password = "simulator".toCharArray();
            KeyStore ks = KeyStore.getInstance("JKS");
            FileInputStream fis = new FileInputStream("testkey.jks");
            ks.load(fis, password);

            // setup the key manager factory
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(ks, password);

            // setup the trust manager factory
            TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
            tmf.init(ks);

            // setup the HTTPS context and parameters
            sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
            server.setHttpsConfigurator(new HttpsConfigurator(sslContext) {
                public void configure(HttpsParameters params) {
                    try {
                        // initialise the SSL context
                        SSLContext context = getSSLContext();
                        SSLEngine engine = context.createSSLEngine();
                        params.setNeedClientAuth(false);
                        params.setCipherSuites(engine.getEnabledCipherSuites());
                        params.setProtocols(engine.getEnabledProtocols());

                        // Set the SSL parameters
                        SSLParameters sslParameters = context.getSupportedSSLParameters();
                        params.setSSLParameters(sslParameters);

                    } catch (Exception ex) {
                        System.out.println("Failed to create HTTPS port");
                    }
                }
            });

            //API del server
            server.createContext("/index/", new AllURIs());
            server.createContext("/bulloni/", new Handler());
            server.createContext("/utensili/", new Handler());
            server.createContext("/vernici/", new Handler());
            server.createContext("/altro/", new Handler());
            server.createContext("/", new Home());

            server.setExecutor((ThreadPoolExecutor) Executors.newFixedThreadPool(5));
            server.start();
            System.out.println("server running on localhost:"+port);
        } catch (Exception e) {
            System.out.println("Failed to create HTTPS server on port " + port + " of localhost");
            e.printStackTrace();
        }
    }

//	public static void main(String[] args) throws IOException {//main HTTP
//		if (args.length > 1 && args[0].equals("-port"))
//			try {
//				port = Integer.parseInt(args[1]);
//			} catch (Exception e) {
//				e.printStackTrace();
//			}
//		ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);//Executors.newWorkStealingPool() doesn't work
//		HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
//
//		server.createContext("/index/", new AllURIs());
//		server.createContext("/bulloni/", new Handler());
//		server.createContext("/utensili/", new Handler());
//		server.createContext("/vernici/", new Handler());
//		server.createContext("/altro/", new Handler());
//		server.createContext("/", new Home());
//
//		server.setExecutor(threadPoolExecutor);
//		server.start();
//
//		System.out.println("server running on localhost:"+port);
//
//	}

    public static String getLocalPage(URI pageid) {
        String line;
        String pageIDString = pageid.toString();
        String page = "./html" + pageIDString.substring(0, pageIDString.length() - 1) + ".txt";// entro nella cartella
        // html e leggo il file
        // txt

        String answer = "";
        if (getExtension(page).length() == 0)
            page += ".html";
        try {
            FileReader fileReader = new FileReader(page);

            BufferedReader bufferedReader = new BufferedReader(fileReader);

            while ((line = bufferedReader.readLine()) != null) {
                answer += (line + "\n");
            }
            bufferedReader.close();
        } catch (FileNotFoundException ex) {
            System.out.println("Unable to open file '" + page + "'");
            return "fail";
        } catch (IOException ex) {
            System.out.println("Error reading file '" + page + "'");
            return "fail";
        }
        return answer;
    }

    private static String getExtension(String file) {
        int i = file.length() - 1;
        while (i > 0 && file.charAt(i) != '.' && file.charAt(i) != '/')
            i--;
        if (file.charAt(i) == '.')
            return file.substring(i + 1);
        else
            return "";
    }

}