// Douglas Fjällrud, Axel Blomén, Grupp 35
package server;

import javax.net.ssl.*;
import java.io.*;
import java.security.*;
import java.security.cert.CertificateException;

public class TLSServerMutual {
    private static final String SERVER_KEYSTORE_PATH = "../server.p12";
    private static final String SERVER_KEYSTORE_PASSWORD = "server";

    private static final String SERVER_TRUSTSTORE_PATH = "serverTrustStore.jks";
    private static final String SERVER_TRUSTSTORE_PASSWORD = "trustpass";

    private static final int TLS_PORT = 8043;

    public static void main(String[] args) {
        try {
            KeyStore serverKeyStore = KeyStore.getInstance("PKCS12");
            try (FileInputStream fis = new FileInputStream(SERVER_KEYSTORE_PATH)) {
                serverKeyStore.load(fis, SERVER_KEYSTORE_PASSWORD.toCharArray());
            }

            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(serverKeyStore, SERVER_KEYSTORE_PASSWORD.toCharArray());
            KeyManager[] keyManagers = kmf.getKeyManagers();

            KeyStore trustStore = KeyStore.getInstance("JKS");
            try (FileInputStream trustFis = new FileInputStream(SERVER_TRUSTSTORE_PATH)) {
                trustStore.load(trustFis, SERVER_TRUSTSTORE_PASSWORD.toCharArray());
            }

            TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
            tmf.init(trustStore);
            TrustManager[] trustManagers = tmf.getTrustManagers();

            SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
            sslContext.init(keyManagers, trustManagers, new SecureRandom());

            SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();
                try (SSLServerSocket sslServerSocket =
                    (SSLServerSocket) sslServerSocketFactory.createServerSocket(TLS_PORT)) {

                    System.out.println("TLS-server startad på port " + TLS_PORT + ".");

                    String[] ciphers = { "TLS_AES_128_GCM_SHA256" };
                    sslServerSocket.setEnabledCipherSuites(ciphers);

                    sslServerSocket.setNeedClientAuth(true);

                while (true) {
                    try (SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
                        BufferedReader br = new BufferedReader(new InputStreamReader(sslSocket.getInputStream()));
                        PrintWriter pw = new PrintWriter(sslSocket.getOutputStream(), true)) {

                        System.out.println("Klient ansluten: " + sslSocket.getInetAddress());

                        String line;
                        while ((line = br.readLine()) != null) {
                            System.out.println("Mottaget: " + line);
                            pw.println("Echo: " + line);
                        }
                        System.out.println("Klient frånkopplad.");
                    } catch (IOException e) {
                        System.err.println("Fel vid hantering av klientanslutning: " + e.getMessage());
                    }
                }
            }
        } catch (KeyStoreException | IOException | NoSuchAlgorithmException
                 | CertificateException | KeyManagementException | UnrecoverableKeyException e) {
            e.printStackTrace();
        }
    }
}