package timingexp;

import java.net.*;
import java.rmi.*;
import Tools.*;

// ssh
import ssh.*;

// ssl
import COM.claymoresystems.ptls.*;
import ssl.*;

// sf
import sdsi.*;
import proof.*;

/**
 * The server side of the RMI performance test harness. Sets up one
 * object of each type to be served; analogous to the fourServers mode
 * of SecureServerConfig.
 */
public class TestRMIServer {
	// create one of each of the supported variations on RMI test objects
	// start with just the basic RMI
	TestRMICall[] trc;

	TestRMIServer(Options opts) {
		try {
			trc = new TestRMICall[4];
			trc[0] = new TestRMICallBasic();

			if (opts.getBoolean("enableSSL")) {
				// switchable because it's semibroken and very slow.
				SSLContext sslContext = new SSLContext();
				sslContext.loadRootCertificates(
					"timingexp/test-server-cert.pem");
					// the test key is its own root; this is a self-signed cert
				sslContext.loadEAYKeyFile("timingexp/test-server-rsa.key",
					"password");
				trc[1] = new TestRMICallSsl(sslContext);
			}

			SSHContext sshContext = SSHContext.getDefault();
			trc[2] = new TestRMICallSsh(sshContext);
	
			trc[3] = new TestRMICallSf(sshContext, getIssuer(opts));
	
			// register each in the rmiregistry
			InetAddress thisHost = InetAddress.getLocalHost();
			for (int i=0; i<trc.length; i++) {
				if (trc[i]==null) {
					continue;
				}
				String registryResourceName = "/TestRMIServer"+i;
				Naming.rebind("//"+thisHost.getHostName()+registryResourceName,
					trc[i]);
				System.out.println("registered in RMIregistry: "
					+registryResourceName);
			}

			Naming.rebind("//"+thisHost.getHostName()+"/Reconfigure",
				new TestRMIReconfigure());
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	Hash getIssuer(Options opts)
		throws Exception {
		String serverKeyLoc = opts.get("publicKey");
		SDSIObject serverObject;
		Hash serverPublicHash;

		if (serverKeyLoc.charAt(0)=='(') {
			// this is an s-expression. Parse it.
			serverObject =
				(SDSIObject) KeyTools.parseString(serverKeyLoc);
		} else {
			serverObject =
				(SDSIObject) KeyTools.processFilename(serverKeyLoc);
		}
		if (serverObject instanceof Hash) {
			serverPublicHash = (Hash) serverObject;
		} else {
			SDSIPrincipal serverPublicKey;
			if (serverObject instanceof SDSIKeyPair) {
				serverPublicKey = ((SDSIKeyPair) serverObject)
					.getPublicKey();
			} else {
				serverPublicKey = (SDSIPrincipal) serverObject;
			}
			serverPublicHash = new Hash("md5", serverPublicKey);
		}

		return serverPublicHash;
	}

	public static void main(String[] args) {
		Options opts = new Options(args) {
			public void defineOptions() {
				programName = getClass().getName();
				defineOption("publicKey",
					"location of or s-expression for the server public key",
					"certs-server/serverkey");
				defineOption("enableSSL",
					"turn on service #1 (SSL)",
					"false");
			}
		};
		TestRMIServer trs = new TestRMIServer(opts);
	}
}
