import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.net.ssl.SSLSocket;

public class Client {

    public static void main(String[] args) throws Exception {
        Utils.adjustProviders();
        startClient();
    }

    private static void startClient() throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(Utils.THREADS);

        List<Future<Void>> futures = new ArrayList<>();
        for (int i = 0; i < Utils.THREADS; i++) {
            Future<Void> future = executor.submit(new Callable<Void>() {

                @Override
                public Void call() throws Exception {
                    connect();
                    return null;
                }
            });
            futures.add(future);
        }

        for (Future<Void> future : futures) {
            future.get();
        }

        executor.shutdown();
    }

    private static void connect() throws Exception {
        SSLSocket socket
                = (SSLSocket) Utils.createSSLContext().getSocketFactory().createSocket();
        try {
            socket.connect(new InetSocketAddress("localhost", Utils.PORT));
            Utils.writeOut(socket.getOutputStream(), "GET /index HTTP/1.1\r\n");
            System.out.println("Client send request");

            String response = Utils.readIn(socket.getInputStream());
            System.out.printf("Client received response: [%s]%n", response);
        } finally {
            socket.close();
            socket.getSession().invalidate();
        }
    }
}
