package examples.xml.biztalk;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.Runtime;
import javax.jms.JMSException;
import javax.naming.NamingException;
import java.lang.InterruptedException;

/**
 * AdminCLU is a command line utility for managing a biztalk server. Fucntions
 * include starting, stopping and configuration of a server.
 * <P>
 * To start:
 * java examples.xml.biztalk.AdminCLU <I>name</I>
 * <P>
 * where <I>name</I> is the name of the server to manage. This name should 
 * correspond to a config file, <I>name</I>.xml.  
 * <P>
 * AdminCLU loops waiting for user input. Recognized requests include:
 * <P>
 * <ul>
 * <li>start - start a server
 * <li>stop - shutdown a server
 * <li>config - reconfig server
 * <li>quit - exit
 * </ul>
 */
public class AdminCLU extends BizAdapter {
  private String outQ;
  private int id = 0;
  private String name;
  private Process BizServerProcess = null;
  BizConfig config;


  public static void main(String[] args) {
    if (args.length != 1) {
      System.out.println("Usage: java examples.xml.biztalk.AdminCLU <name>");
      System.exit(0);
    }
    AdminCLU me = new AdminCLU();

    me.process(args[0]);
    try {
      me.closeOutQ();
    }
    catch (JMSException jmse) {
    }
  }

  public AdminCLU() {}

  private void process(String n) {
    name = n;
    // 
    // get a copy of the config info this server would use
    //
    config = new BizConfig();
    if (!config.loadConfig(name)) {
      System.out.println("No such Bizserver("+name+")");
      System.exit(0);;
    }
    // 
    // connect to server's incoming queue
    //
    try {
      outQ = config.getInQ();
      initOutQ(outQ);
    }
    catch (NamingException jmse) {
      System.out.println("Can't connect to server queue");
      System.exit(0);;
    }
    catch (JMSException jmse) {
      System.out.println("Can't connect to server queue");
      System.exit(0);;
    }

    //
    // get requests from stdin
    //
    BufferedReader msgStream = new BufferedReader(new InputStreamReader(System.in));
    String line=null;
    boolean quitNow = false;
    do {
      System.out.print("Enter request (\"quit\" to quit): ");
      id++;
      try {
        line = msgStream.readLine();
      }
      catch (IOException ioe) {
        System.out.println("Can't read from stdin.");
	return;
      }
      if (line != null && line.trim().length() != 0) {
        quitNow = line.equalsIgnoreCase("quit");
	if (!quitNow) {
	  if (line.equals("start")) {
	    startServer();
	  }
	  if (line.equals("stop")) {
	    stopServer();
	  }
	  if (line.equals("config")) {
	    configServer();
	  }
	} else if (BizServerProcess != null) {
          stopServer();
        }
      }
    } while (! quitNow);
  }

  private void startServer() {
    String[] cmdArray = new String[3];
    cmdArray[0] = "java";
    cmdArray[1] = "examples.xml.biztalk.BizServer";
    cmdArray[2] = name;
    try {
      BizServerProcess = Runtime.getRuntime().exec(cmdArray);
    }
    catch (IOException ioe) {
      System.out.println("Unable to execute "+cmdArray[1]);
    }
  }

  private void stopServer() {
    DOMOutgoingMessage msg = new DOMOutgoingMessage();
    //
    // set each field and convert to string XML
    //
    msg.setType(BizConfig.BIZ_STOP);
    msg.setNameSpace();
    msg.setFromAddress("AdminCLU");
    msg.setFromReferenceID("");
    msg.setFromProcess("");
    msg.setFromHandle("");
    msg.setToAddress(config.getURI());
    msg.setToReferenceID("");
    msg.setToProcess("");
    msg.setToHandle("");
    msg.setDocName("Biz Admin");
    msg.setDocDesc("Shutdown request");
    msg.setMsgID(Integer.toString(id));
    msg.setMsgSubject("Shutdown request");
    msg.setTimeStamp();
    msg.setBodyAsXML("<"+BizConfig.BIZ_STOP+">Shutdown </"+BizConfig.BIZ_STOP+">");

    try {
      System.out.println("Sending: "+msg.toString());
      send(msg.toString());
      Thread.sleep(4000);
      if (BizServerProcess != null) {
        BizServerProcess.destroy();
      }
    } catch (JMSException jmse) {
      System.out.println("Unable to queue request to server.");
      System.out.println("JMSException: "+jmse.getMessage());
    } catch (InterruptedException ie) {
      ie.printStackTrace();
    }
  }

  private void configServer() {
    DOMOutgoingMessage msg = new DOMOutgoingMessage();
    //
    // set each field and convert to string XML
    //
    msg.setType(BizConfig.BIZ_ADMIN);
    msg.setNameSpace();
    msg.setFromAddress("AdminCLU");
    msg.setFromReferenceID("");
    msg.setFromProcess("");
    msg.setFromHandle("");
    msg.setToAddress(config.getURI());
    msg.setToReferenceID("");
    msg.setToProcess("");
    msg.setToHandle("");
    msg.setDocName("Biz Admin");
    msg.setDocDesc("Config request");
    msg.setMsgID(Integer.toString(id));
    msg.setMsgSubject("Config request");
    msg.setTimeStamp();
    msg.setBodyAsXML("<"+BizConfig.BIZ_ADMIN+">Config </"+BizConfig.BIZ_ADMIN+">");

    try {
      System.out.println("Sending: "+msg.toString());
      send(msg.toString());
    }
    catch (JMSException jmse) {
      System.out.println("Unable to queue request to server.");
      System.out.println("JMSException: "+jmse.getMessage());
    }
  }
}
