package org.huihoo.jfox.mx;

import java.util.Properties;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.lang.reflect.Method;

import org.jfox.mx.MxRegistration;
import org.jfox.mx.MxServer;
import org.jfox.mx.ObjectName;
import org.jfox.mx.Mxable;
import org.huihoo.jfox.system.State;
import org.huihoo.jfox.system.ServiceSupport;

/**
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class ShutdownHookMX implements ServiceMX, MxRegistration {
  private MxServer server = null;
  private ShutdownHook shutdownHook = null;
  private Thread shutdownThread = null;
  private boolean started = false;

  public void mx_start() {
    if(started) return;
    try {
      shutdownHook = new ShutdownHook();
      shutdownHook.init();
      shutdownHook.start();
      shutdownThread = new Thread(shutdownHook);
      Runtime.getRuntime().addShutdownHook(shutdownThread);
      started = true;
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void mx_stop() {
    started = false;
    Runtime.getRuntime().removeShutdownHook(shutdownThread);
//    shutdownThread = null;
//    shutdownHook = null;
  }

  public void mx_stopJFox(){
    try {
      shutdownHook.stop();
      shutdownHook.destroy();
      started = false;
//      mx_stop();
    }
    catch (Exception e) {
      e.printStackTrace();
    }

  }

  public State mx_getStat() {
    return started ? State.STARTED : State.STOPPED;
  }

  public String getMxDescription() {
    return "";
  }

  public Properties getOperationDescriptions() {
    return null;
  }

  public Object getSource() {
    return shutdownHook;
  }

  public void postDeregister() {
  }

  public void preRegister(MxServer server, ObjectName name) throws Exception {
    this.server = server;
  }

  public void postRegister(Boolean registrationDone) {

  }

  public void preDeregister() throws Exception {

  }

  class ShutdownHook extends ServiceSupport {

    protected void doInit() throws Exception {

    }

    protected void doStart() throws Exception {

    }

    protected void doStop() throws Exception {
      Iterator mxes = server.queryMX("*");
      List laters = new ArrayList();
      while(mxes.hasNext()){
        ObjectName mxObject = (ObjectName)mxes.next();
        Mxable mx = server.getMxObject(mxObject);
        if(mx instanceof NamingServiceMX){
          laters.add(mx);
        }
        else if(mx instanceof ServiceMX){
          if(!(mx instanceof ShutdownHookMX)) {
            ((ServiceMX)mx).mx_stop();
          }
        }
        else {
          try {
            Method method = mx.getClass().getMethod("mx_stop",null);
            method.invoke(mx,null);
          }
          catch(NoSuchMethodException e){

          }

        }
      }
      for(int i=0; i<laters.size(); i++){
        ((ServiceMX)laters.get(i)).mx_stop();
      }
      Thread.sleep(1000L);
    }

    protected void doDestroy() throws Exception {

    }

    public void run() {
      if (started) {
        mx_stopJFox();
      }
    }
  }

  public static void main(String[] args) {

  }
}