// file: $ISIP_IFC/util/demo/isip_comm_server_process_manager/ProcessManager.java
//version: $Id: ProcessManager.java 10102 2005-05-20 19:18:44Z elliott $
//

// import necessary java libraries
//
import java.net.*;
import java.io.*;
import java.util.*;

/** 
 * Accepts the connection from UI and starts DemoClientHandler for this
 * UI.
 */
public class ProcessManager implements Runnable {
    
    //-------------------------------------------------------------------------
    //
    // public constants
    //
    //-------------------------------------------------------------------------


    //------------------------------------------------------------------------
    //
    // protected data
    //
    //-----------------------------------------------------------------------
    
    /**
     * ServerSocket object.
     */
    protected static ServerSocket serverSocket_d; 

    /**
     * Default server port number.
     */
    protected static int server_port_d = 9000;     

    /**
     * Default hub port number.
     */
    protected static int DEFAULT_HUB_PORT = 25010;     

    /**
     * Maximum hub port number.
     */
    protected static int MAX_HUB_PORT = 45010;

    /**
     * Current hub port number.
     */
    protected int hub_port_d = DEFAULT_HUB_PORT;

    //-------------------------------------------------------------------------
    //
    // public methods
    //
    //-------------------------------------------------------------------------
       
    /**
     * Constructor for process manager.
     *
     * @param port_a The port number this server will listen.
     */
    public ProcessManager(int port_a) {

        // create the server socket...
	//
        try {
            serverSocket_d = new ServerSocket(port_a);
        }
        catch(IOException e) {
            System.out.println("-> Could not create Server on port " + port_a);
            System.exit(1);
        }
        
        System.out.println("-> Server created on port " + port_a);
    }
    
    /** 
     * When this thread is started, this method is called.  
     *
     * @return void.
     */
    public void run() {

	// local variables
	//
	int numberConnection = 0;

	System.out.println("-> Waiting for client " +
			   "connections...new pid management...");

	// infinite loop to accept client's connection
	//
        while (true) {
  
            // wait for a client connection...
	    //
            try {
		new DemoClientHandler(serverSocket_d.accept(), hub_port_d);
            }
            catch (IOException e) {
                System.out.println("-> Error accepting client connection: " 
				   + e);
            }

	    // Make sure the port doesn't go too high
	    //
	    if (++hub_port_d >= MAX_HUB_PORT) {
		hub_port_d = DEFAULT_HUB_PORT;
	    }
        }
    }
    

    //-------------------------------------------------------------------------
    //
    // printUsage method for this class
    //
    //-------------------------------------------------------------------------

    /**
     * Usage of this class. Prints using System.out.println() and then returns
     *
     * @param exec_name_a String name of executable
     *
     * @return void.
     */
    public static void printUsage(String exec_name_a) {
	
	//TODO, change this print message
	System.out.println("Usage: " + exec_name_a + " [port]");
	System.out.println("\nExample:\n   " + exec_name_a + " 25075\n");
	System.out.println("This server is the ProcessManager for the dialog" +
			   " demos. There is a single\noptional argument of " +
			   "a port number.\nIf it is not present, the " +
			   "default port number is 9000.");
			   
    }

    //-------------------------------------------------------------------------
    //
    // main method for this class
    //
    //-------------------------------------------------------------------------
    
    /**
     * Main method for this class. Create a new ProcessManager and
     * start a new thread for this server
     *
     * @param args arguments from the command line.
     *
     * @return void.
     */
    public static void main(String args[]) { 
	
	// get arguments for port number if exists
	// if something happens and cannot parse it, print out how to use it
	// along with stack
	//
	try {
	    // Attempt to parse the port number
	    //
	    if (args.length > 0) {
		server_port_d = Integer.parseInt(args[0]);
	    }
	}
	catch (Exception ex) {
	    System.out.println("Error! Not correct command line " +
			       "parameters.\n");
	    ProcessManager.printUsage("isip_process_manager");
	    // Don't really care about stack trace
	    //
	    // ex.printStackTrace();
	    System.exit(1);
	}	
	
        // create the process manager server...
	//
	ProcessManager server = new ProcessManager(server_port_d);
	
	// start a new thread for this connection
	//
        new Thread(server).start();
    }
}
