
package jmxclcl;

import java.util.Properties;

import java.net.InetAddress;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import common.TestParamsRMISSL;
import common.RMISSLClientSocketFactory;
import common.RMISSLServerSocketFactory;

public class TestParamsRMISSLClient {

  
  static boolean TRACE = false;
  static void out (Object msg) { System.out.println("TestParams RMISSL Client: " +  msg); }

  static String serverName = "TestParamServer";
  private static int port = 2019;
  private static int handshakeTimeout = 10000;
  private static String host;
  private static RMISSLClientSocketFactory factory;
  static boolean isDefaultKM = true;

  public static void main(String args[]) {
    if (args.length > 3) { // trace is on
      TRACE = true;
      RMISSLClientSocketFactory.TRACE = true;
    }
    if (args.length > 2) {
      try {
        handshakeTimeout = 1000 * Integer.parseInt(args[2]);
      } catch (Exception e) {
        out("Error: startup timeout value is not an integer");
        System.exit(1);
      }
    }
    if (args.length > 1) {
      try {
        port = Integer.parseInt(args[1]);
      } catch (Exception e) {
        out("Error: port value is not an integer");
        System.exit(1);
      }
    }

    if (TRACE) {
      out("port = " + port);
      out("handshakeTimeout = " + handshakeTimeout);
    }
    
    if (args.length > 0 && args[0].toLowerCase().indexOf("ssl") > -1) {
      isDefaultKM  = args[0].toLowerCase().indexOf("dflt") > -1;
      setup_SSL();
    }
    else 
      setup_no_SSL();

    if (args.length > 0 && args[0].toLowerCase().indexOf("rmi") > -1)
      perfRMI();
  }
  

  static void setup_no_SSL() {
    if (TRACE) out("RMI plain");

    try {
      factory = null;
    } catch (Exception e) {
      out("TestParamsRMISSLClient setup_no_SSL exception: " + e.getMessage());
      e.printStackTrace();
    }
  }

  static void setup_SSL() {
    if (TRACE) out("RMI with SSL");

    try {
      // Make reference to SSL-based registry
      factory = new RMISSLClientSocketFactory(isDefaultKM);
      if (TRACE) out("SSL connection factory = " + factory);

    } catch (Exception e) {
      out("TestParamsRMISSLClient setup_SSL exception: " + e.getMessage());
      e.printStackTrace();
    }
  }

  static void perfRMI() {

    try {
      if (host == null) {
        host = InetAddress.getLocalHost().getHostName();
        if (TRACE) out("host = " + host);
      }
    } catch (Exception e) {
      out("TestParamsRMISSLClient perfRMI()  exception: " + e.getMessage());
      e.printStackTrace();
      return;
    }
    
    Registry registry = null;
    try {
      TestParamsRMISSL server = null;
      {
        long timeStamp = System.currentTimeMillis();
        int wait_ms = 1000;

        while (server == null) {
          try {
            if (registry == null) {
              registry = (factory == null)
                ? LocateRegistry.getRegistry(host, port)
                : LocateRegistry.getRegistry(host, port, factory);
              if (TRACE) out("registry = " + registry);
            }
            server = (TestParamsRMISSL) registry.lookup(serverName);
            if (TRACE) out("server = " + server);

          } catch (Exception e) { 
            if (TRACE) out("while obtaining TestParamsRMISSL proxy, got " + e);
            if (TRACE) e.printStackTrace(System.out);
            // note: it seems as only SSL mode goes here; no_SSL mode waits for
            // lookup until SocketTimeoutException.
            if (System.currentTimeMillis() < timeStamp + handshakeTimeout) {
              //not needed... if (registry != null) registry.unbind(serverName);
              out("Wait additional " + wait_ms + "ms for connection...");
              Thread.sleep(wait_ms);
              wait_ms += (wait_ms/4);
            }
            else {
              throw e;
            }
          }
        }
      }
          
      long start = System.currentTimeMillis();
      int howMany = 10;

      for (int i = 0; i < howMany; i++)
        server.retInt();

      long time = System.currentTimeMillis() - start;
      out("\n" + howMany + " empty trips took " + time + " ms, or " + (time/(double)howMany) + " ms per trip.\n");

      start = System.currentTimeMillis();
      
      String[] report = new String[howMany];

      for (int i = 0; i < howMany; i++) {
        String valString = server.retString();
        int valInt = server.retInt();
        double valDouble = server.retDouble();
        double sqrt = server.retMathSqrt(i);
        Properties p = server.retProperties();
        String[] valArr = server.retStrings();
        long rep_start = System.currentTimeMillis();
        int chars = 0;
        for (int k = 0; k < valArr.length; k++)
          chars += valArr[k].length();
        
        report[i] = "\n valString = " + valString +
          "\n  vaInt = " + valInt + 
          "\n  valDouble = " + valDouble + 
          "\n  sqrt = " + sqrt + 
          "\n  props of size = " + p.size() + 
          "\n  array of strings of length = " + valArr.length + ", total chars = " + chars +
          "\n";
        start += (System.currentTimeMillis() - rep_start);
      }

      time = System.currentTimeMillis() - start;
      String header  = "Test RMI" + (factory == null ? "" : " SSL");
      System.out.println("\n" + header + " stats:\n" + howMany + " trips took " + time + " ms, or " + (time/(double)howMany) + " ms per trip.\n");
      
      System.out.println("\n first trip data:" + report[0]);
      System.out.println("\n last  trip data:" + report[report.length-1]);

      if (TRACE) out("Shutting down server...");
      server.shutDown();
      // force RMI to disconnect and quit
      System.exit(0);

    } catch (Exception e) {
      out("TestParamsRMISSLClient perfRMI()  exception: " + e.getMessage());
      e.printStackTrace();
    }
  }
}


