package primer_client;

import java.net.*;
import java.io.*;

import javax.net.ssl.*;

public class client implements HandshakeCompletedListener, Runnable {
	private static final int SSL_ECHO_PORT = 7000;

	private final static String KS_PATH = "client.jks";
	private final static String KS_PASS = "changeit";

	private final static String TS_PATH = "servers.jks";
	private final static String TS_PASS = "changeit";

	public static void main(String[] args) throws Exception {
		(new client()).run(args);
	}

	private Socket socket;

	private void run(String[] args) throws Exception {
		String host = "www.ssjava.net";
		int port = SSL_ECHO_PORT;
		boolean clientAuth = false;

		for (int i = 0; i < args.length; i++) {
			if ("-host".equals(args[i]))
				host = args[++i];
			else if ("-port".equals(args[i]))
				port = Integer.parseInt(args[++i]);
			else if ("-clientauth".equals(args[i]))
				clientAuth = true;
			else {
				System.out.println("Usage: java client -host <host> [-port <port>] [-clientauth]");
				return;
			}
		}

		System.out.println("server = " + host + ":" + port);

		System.setProperty("javax.net.ssl.trustStore", TS_PATH);
		System.setProperty("javax.net.ssl.trustStorePassword", TS_PASS);

		if (clientAuth) {
			System.setProperty("javax.net.ssl.keyStore", KS_PATH);
			System.setProperty("javax.net.ssl.keyStorePassword", KS_PASS);
		}

		SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
		System.out.println("factory created");

		socket = factory.createSocket(host, port);
		((SSLSocket) socket).addHandshakeCompletedListener(this);
		System.out.println("socket created");

		PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8"));

		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

		Thread t = new Thread(this);
		t.start();

		System.out.println("sender started");

		while (true) {
			String s = in.readLine();
			if (s == null)
				s = ".";

			out.println(s);
			out.flush();

			if (s.equals("."))
				break;
		}

		System.out.println("sender exit");

		t.join();
		out.close();
		socket.close();
	}

	public void run() // receiver thread
	{
		System.out.println("receiver started");

		try {
			BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8"));

			String s;
			while ((s = in.readLine()) != null) {
				System.out.println(s);
				if (s.equals("."))
					break;
			}
			in.close();
		} catch (Exception e) {
			System.err.println("receiver thread: " + e);
		}

		System.out.println("receiver exit");
	}

	public void handshakeCompleted(HandshakeCompletedEvent event) {
		System.out.println("handshake completed");

		try {
			System.out.println("getCipherSuite: " + event.getCipherSuite());

			SSLSession session = event.getSession();
			System.out.println("getProtocol: " + session.getProtocol());
			System.out.println("getPeerHost: " + session.getPeerHost());

			java.security.cert.Certificate[] certs = event.getPeerCertificates();
			for (int i = 0; i < certs.length; i++) {
				if (!(certs[i] instanceof java.security.cert.X509Certificate))
					continue;
				java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate) certs[i];
				System.out.println("Cert #" + i + ": " + cert.getSubjectDN().getName());
			}
		} catch (Exception e) {
			System.err.println("handshakeCompleted: " + e);
		}
	}
}
