
package jmxserv;

import sun.management.Agent;
import java.util.*;
import java.io.IOException;
import java.io.FileInputStream;

import common.RMISSLServerSocketFactory;
import common.RMISSLClientSocketFactory;

public class Load implements common.WorkLoadMBean {
  static boolean TRACE = false;
  static void out (String msg) { System.out.println("JMX WorkLoad: " + msg); }

  //-- operations

  public void stop() {
    resetLoad(count1max, count2max, count3max, sleepMSecs, 0);
  }
  public void start() {
    medium();
  }

  //-- attributes

  public boolean getTrace() { return TRACE; }
  public void setTrace(boolean val) { TRACE = val; TestParamsRMISSLImpl.TRACE = val; }

  public int getCount1max() { return count1max; }
  public void setCount1max(int val) { count1max = val; }

  public int getCount2max() { return count2max; }
  public void setCount2max(int val) { count2max = val; }

  public int getCount3max() { return count3max; }
  public void setCount3max(int val) { count3max = val; }

  public int getSleepMSecs() { return sleepMSecs; }
  public void setSleepMSecs(int val) { sleepMSecs = val; }

  public int getDurationMaxMins() { return durationMaxMins; }
  public void setDurationMaxMins(int val) { durationMaxMins = val; }

  public int getCount1() { return count1; }
  public void setCount1(int val) { count1 = val; }

  public int getCount2() { return count2; }
  public void setCount2(int val) { count2 = val; }

  public int getCount3() { return count3; }
  public void setCount3(int val) { count3= val; }

  public int getTableSize() { if (tab == null) return 0; else return tab.size(); }
  public String getJunk() { return junk; }

  //-- non-mbean static methods and state

  public static void heavy () {
    resetLoad(1000, 100, 100, 100, 60);
    doLoad();
  }

  public static void medium () {
    resetLoad(400, 10, 100, 10, 10);
    doLoad();
  }

  public static void light () {
    resetLoad(100, 10, 50, 10, 1);
    doLoad();
  }

  // obsolete...
  // public static void sleep5min (String args[]) {
  //   try {
  //     Thread.sleep(5 * 60 * 1000);
  //   } catch (Exception e) {
  //     out("sleep5min exception: " + e);
  //   }
  // }


  static double d_val = Math.random();

  static double computeVal () {
    if (d_val < 0.1) {
      Thread thread = new Thread () {
          public void run() {
            while (true) {
              d_val = Math.random();
              if (d_val >= 0.1) { stop(); return; }
              //sleep(30); // 30ms
            }}};
      thread.start();
    }
    return d_val;
  }

  static String hashtableToText (Hashtable p) {
    String result = "";
    for (Enumeration e = p.keys() ; e.hasMoreElements() ;) {
      String key = e.nextElement().toString();
      String val = p.get(key).toString();
      result += ("\n" + key + " = " + val);
    }
    return result;
  }

  // todo: consider moving the state into bean's instance variables.

  static int count1max;
  static int count2max;
  static int count3max;
  static int sleepMSecs;
  static int durationMaxMins;

  synchronized static void resetLoad(int count1max, int count2max, int count3max, int sleepMSecs, int durationMaxMins) {
    Load.count1max = count1max;
    Load.count2max = count2max;
    Load.count3max = count3max;
    Load.sleepMSecs = sleepMSecs;
    Load.durationMaxMins = durationMaxMins;
  }

  static Hashtable tab;
  static String junk;
  static int count1, count2, count3;

  static void doLoad() {
    long timer_start = System.currentTimeMillis();
    try {
      junk = "";
      for (count1 = 0; 
           count1 < count1max && 
             (System.currentTimeMillis() - timer_start)/60000.0 < durationMaxMins;
           count1++) {
        tab = new Hashtable();
        for (count2 = 0; count2 < count2max; count2++) {
          Thread.sleep(sleepMSecs);
          for (count3 = 0; count3 < count3max; count3++) 
            tab.put(""+count2+"-"+count3, "" + computeVal());
          junk += hashtableToText(tab);
        }
        System.out.print(". ");
        junk = "";
      }
    } catch (Exception e) {
      out("heavy load exception: " + e);
    }
  }

  //-- properties 

  static void dump (Hashtable p) {
    for (Enumeration e = p.keys() ; e.hasMoreElements() ;) {
      String key = e.nextElement().toString();
      String val = p.get(key).toString();
      System.out.println("\n" + key + " = " + val);
    }
  }

  public static void dumpSysProps (String unused[]) {
    dump(System.getProperties());
  }

  public static Properties propertiesFromFile(String fname)
    throws IOException {
    Properties p = new Properties();
    if (fname == null)
      return p;
    FileInputStream fin = new FileInputStream(fname);
    p.load(fin);
    fin.close();
    return p;
  }

  public static void  dumpPropertiesFromFile(String fname) {
    try {
      dump(propertiesFromFile(fname));
    } catch (Exception e) {
      out("+++++++++++  e: " + e);
      e.printStackTrace(System.out);
    }
  }

  //-- Register MBeans

  static void reportBeanRegisteringError (String name, Exception e) {
    out("When registering bean " + name + " got exception: " + e);
  }

  public static void addDBProps () {
    registerMBean("DBProps", DBProps.class, common.DBPropsMBean.class);
  }

  public static void addOJVM () {
    registerMBean("OJVM", OJVM.class, common.OJVMMBean.class);
  }

  public static void addWorkLoad () {
    registerMBean("Load", Load.class, common.WorkLoadMBean.class);
  }

  public static void addPermissionManager () {
    registerMBean("PermissionManager", PermissionManager.class, common.PermissionManagerMBean.class);
  }

  public static void addFilePermissionMB () {
    registerMBean("FilePermission", jmxserv.FilePermission.class, common.FilePermissionMBean.class);
  }

  public static void addPropertyPermissionMB () {
    registerMBean("PropertyPermission", jmxserv.PropertyPermission.class, common.PropertyPermissionMBean.class);
  }


  static void registerMBean (String name, Class  mbeanImplClass, Class interfaceClass) {
    try {
      javax.management.MBeanServer mbs = 
        java.lang.management.ManagementFactory.getPlatformMBeanServer(); 

      javax.management.ObjectName objName = 
        new javax.management.ObjectName("jmxserv:type=" + name); 

      Object mbeanImpl  = mbeanImplClass.newInstance();

      javax.management.StandardMBean mbean = 
        new javax.management.StandardMBean(mbeanImpl, interfaceClass);

      mbs.registerMBean(mbean, objName); 
    }
    catch (javax.management.MalformedObjectNameException e) {
      reportBeanRegisteringError(name, e);
    }
    catch (javax.management.InstanceAlreadyExistsException e) {
      reportBeanRegisteringError(name, e);
    }
    catch (javax.management.MBeanRegistrationException e) {
      reportBeanRegisteringError(name, e);
    }
    catch (javax.management.NotCompliantMBeanException e) {
      reportBeanRegisteringError(name, e);
    }
    catch (java.lang.InstantiationException e) {
      reportBeanRegisteringError(name, e);
    }
    catch (java.lang.IllegalAccessException e) {
      reportBeanRegisteringError(name, e);
    }
  }

  // entry point to setup programmaic SSL for JMX
  public static void setup_SSL(String km) {
    boolean isDefault = km.toLowerCase().equals("default");

    TRACE = true;
    RMISSLServerSocketFactory.TRACE = true;
    RMISSLClientSocketFactory.TRACE = true;

    try {
      RMISSLServerSocketFactory ssf = new RMISSLServerSocketFactory(isDefault);
      RMISSLClientSocketFactory csf = new RMISSLClientSocketFactory(isDefault);
    } catch (Exception e) {
      out("Error: " + e.getMessage());
      e.printStackTrace();
      System.exit(1);
    }
  }




  //-- Prepare SSL settings
  //   this is to be use in conjucntion withe the logic of javavm/demo/Makefile
  // 
  // public static void setupSSLconfig () {
  //   common.RMISSLServerSocketFactory.setupSSL();
  // }

  //-- Obsolete... 

  // public static void justAgent(String args[]) {
  //   try {
  //     System.setProperty("com.sun.management.jmxremote.port", "9999");
  //     System.setProperty("com.sun.management.jmxremote.ssl","false");
  //     System.setProperty("com.sun.management.jmxremote.authenticate","false");
  //     System.out.println(" ------------- calling Agent.startAgent");
  //     Agent.startAgent();
  //   } catch (Exception e) {
  //     out("exception: " + e);
  //     e.printStackTrace(System.out);
  //   }
  // 
  // }
  // 
  // 
  // public static void main(String args[]) {
  //   try {
  //     System.setProperty("com.sun.management.jmxremote.port", "9999");
  //     System.setProperty("com.sun.management.jmxremote.ssl","false");
  //     System.setProperty("com.sun.management.jmxremote.authenticate","false");
  // 
  //     System.setProperty("com.sun.jmx.trace.level","DEBUG");
  // 
  //     // System.setProperty("sun.management.compiler","compiler");
  // 
  //     // System.setProperty("jmx.remote.protocol.provider.pkgs", "com.sun.jmx.remote.provider");
  // 
  //     System.out.println(" ------------- calling Agent.startAgent");
  // 
  //     Agent.startAgent();
  // 
  //     // dump(System.getProperties());
  // 
  //     heavy();
  //   } catch (Exception e) {
  //     out("exception: " + e);
  //     e.printStackTrace(System.out);
  //   }
  // 
  // }
  // 
  // public static void activateDaemon(String args[]) {
  //   Thread thread = new Thread () {
  //       public void run() {
  //         System.setProperty("com.sun.management.jmxremote.port", "9999");
  //         System.setProperty("com.sun.management.jmxremote.ssl","false");
  //         System.setProperty("com.sun.management.jmxremote.authenticate","false");
  //         System.out.println(" ------------- calling Agent.startAgent");
  //         
  //         try {
  //           Agent.startAgent();
  //         } catch (Exception e) {
  //           out("exception: " + e);
  //           e.printStackTrace(System.out);
  //         }
  // 
  //         while (true) {
  //           try {
  //             Thread.sleep(50);
  //           } catch (InterruptedException x) {
  //           }
  //           System.out.println(" -- In run method: woke up again");
  //         }
  //       }};
  //   thread.setDaemon(true);
  //   thread.setName("JMX Agent");
  //   thread.start();
  //   try {
  //     Thread.sleep(20000);
  //   } catch (InterruptedException x) {
  //   }
  //   System.out.println("--Leaving activateDaemon method");
  // }

  

}




