package jacorb.imr.util;

import jacorb.imr.*;
/**
 * This class is a command-line tool for administering 
 * the implementation repository.
 * 
 * @author Nicolas Noffke
 * 
 * $Id: ImRManager.java,v 1.10 2000/04/04 12:19:10 noffke Exp $
 */

public class ImRManager {
    private static jacorb.orb.ORB m_orb;

    /**
     * Add a server to the repository or edit an existing server.
     *
     */
    public static void addServer(String[] args){
      if (args.length < 2){
	System.out.println("Please specify a server name");
	usage();
      }

	String _server_name = args[1];
	String _host = null;
	String _command = null;

	try {
	    //evaluate parameters
	    for (int i = 2; i < args.length ; i++){
		if( args[i].equals("-h")){		
		    if (_host == null){
			_host = args[++i];
		    }
		    else
			usage();
		}
		else if( args[i].equals("-c")){		
		    if (_command == null)
			_command = args[++i];
		}
		else{
		    System.out.println("Unrecognized switch: " + args[i]);
		    usage();
		}
	    }

	    if (_host == null)
		_host = java.net.InetAddress.getLocalHost().getHostName();
		    
	}catch (Exception _e){
	    _e.printStackTrace();
	    usage();
	}

	if (_server_name == null || _host == null)
	    usage();
	
	if (_command == null)
	    _command = "";
	
	Admin _admin = AdminHelper.narrow(ImplementationRepositoryImpl.getImR(m_orb));
	if (_admin == null){
	    System.out.println("Unable to connect to repository process!");
	    System.out.println("Please check, if the URL and the IOR file path point to the same file.");
	    System.out.println("Properties jacorb.imr.ior_file and");
	    System.out.println("jacorb.ImplementationRepositoryURL");

	    System.exit(-1);
	}

	try{
	    if (args[0].equals("add"))
		_admin.register_server(_server_name, _command, _host); 
	    else
		_admin.edit_server(_server_name, _command, _host);

	    System.out.println("Server " + _server_name + " successfully " + args[0] + "ed");
	}catch (Exception _e){
	    _e.printStackTrace();
	}

	System.exit(0);
    }

    /**
     * Remove a server or host from the repository.
     */
    public static void remove(String[] args){
      if (args.length < 3)
	usage();
    
	Admin _admin = AdminHelper.narrow(ImplementationRepositoryImpl.getImR(m_orb));
	if (_admin == null){
	    System.out.println("Unable to connect to repository process!");
	    System.out.println("Please check, if the URL and the IOR file path point to the same file.");
	    System.out.println("Properties jacorb.imr.ior_file and");
	    System.out.println("jacorb.ImplementationRepositoryURL");

	    System.exit(-1);
	}

	if (args[1].equals("server")){
	  try{
	    _admin.unregister_server(args[2]);
	    
	    System.out.println("Server " + args[2] + " successfully removed");	      
	  }catch (Exception _e){
	    _e.printStackTrace();
	  }
	}
	else if (args[1].equals("host")) {
	  try{
	    _admin.unregister_host(args[2]);
	    
	    System.out.println("Host " + args[2] + " successfully removed");	      
	  }catch (Exception _e){
	    _e.printStackTrace();
	  }
	}
	else
	  System.out.println("Unknown command " + args[1]);

	System.exit(0);
    }

    /**
     * List servers or hosts.
     */
    public static void list(String[] args){
      if (args.length < 2){
	System.out.println("Please use (servers | hosts) in command");
	usage();
      }

	Admin _admin = AdminHelper.narrow(ImplementationRepositoryImpl.getImR(m_orb));
	if (_admin == null){
	    System.out.println("Unable to connect to repository process!");
	    System.out.println("Please check, if the URL and the IOR file path point to the same file.");
	    System.out.println("Properties jacorb.imr.ior_file and");
	    System.out.println("jacorb.ImplementationRepositoryURL");

	    System.exit(-1);
	}
	
	try{
	    if (args[1].equals("servers")){
		ServerInfo[] _info = _admin.list_servers();
		System.out.println("Servers (total: " + _info.length + "):");
		for(int _i = 0; _i < _info.length; _i++){
		    System.out.println((_i + 1) + ") " +_info[_i].name);
		    System.out.println("   " + "Host: " + _info[_i].host);
		    System.out.println("   " + "Command: " + _info[_i].command);
		    System.out.println("   " + "active: " + ((_info[_i].active)?"yes":"no"));
		    System.out.println("   " + "holding: " + ((_info[_i].holding)?"yes":"no"));
		}
	    }
	    else if (args[1].equals("hosts")){
		HostInfo[] _info = _admin.list_hosts();
		System.out.println("Hosts (total: " + _info.length + "):");
		for(int _i = 0; _i < _info.length; _i++)
		    System.out.println((_i + 1) + ") " +_info[_i].name);
	    }
	    else {
		System.out.println("Unrecognized option: " + args[1]);
		usage();
	    }
	}catch (Exception _e){
	    _e.printStackTrace();
	}
	System.exit(0);
    }

    /**
     * Hold a server.
     */
    public static void holdServer(String[] args){
      if (args.length < 2){
	System.out.println("Please specify a server name");
	usage();
      }
	String _server_name = args[1];
	int _timeout = 0;

	Admin _admin = AdminHelper.narrow(ImplementationRepositoryImpl.getImR(m_orb));	
	if (_admin == null){
	    System.out.println("Unable to connect to repository process!");
	    System.out.println("Please check, if the URL and the IOR file path point to the same file.");
	    System.out.println("Properties jacorb.imr.ior_file and");
	    System.out.println("jacorb.ImplementationRepositoryURL");

	    System.exit(-1);
	}

	try{
	    if (args.length == 3)
		_timeout = Integer.parseInt(args[2]);

	    _admin.hold_server(_server_name);
	    System.out.println("Server " + _server_name + " set to holding");
 	    
	    if (_timeout > 0){
		Thread.sleep(_timeout);
		_admin.release_server(_server_name);
		System.out.println("Server " + _server_name + " released");
	    }

	}catch (Exception _e){
	    _e.printStackTrace();
	}
	System.exit(0);
    }

    /**
     * Release a server.
     */
    public static void releaseServer(String[] args){
      if (args.length < 2){
	System.out.println("Please specify a server name");
	usage();
      }

	String _server_name = args[1];
	int _timeout = 0;

	Admin _admin = AdminHelper.narrow(ImplementationRepositoryImpl.getImR(m_orb));
	if (_admin == null){
	    System.out.println("Unable to connect to repository process!");
	    System.out.println("Please check, if the URL and the IOR file path point to the same file.");
	    System.out.println("Properties jacorb.imr.ior_file and");
	    System.out.println("jacorb.ImplementationRepositoryURL");

	    System.exit(-1);
	}

	try{
	    _admin.release_server(_server_name);
	    System.out.println("Server " + _server_name + " released");
	}catch (Exception _e){
	    _e.printStackTrace();
	}
	System.exit(0);
    }

    /**
     * Write a backup of the server table.
     */
    public static void saveTable(){
	Admin _admin = AdminHelper.narrow(ImplementationRepositoryImpl.getImR(m_orb));	

	try{
	    _admin.save_server_table();
	    System.out.println("Backup of server table was successfull");
	}catch (Exception _e){
	    _e.printStackTrace();
	}
	System.exit(0);
    }

    /**
     * Shut the repository down.
     */
    public static void shutdownImR(String[] args){
	Admin _admin = AdminHelper.narrow(ImplementationRepositoryImpl.getImR(m_orb));
	if (_admin == null){
	    System.out.println("Unable to connect to repository process!");
	    System.out.println("Please check, if the URL and the IOR file path point to the same file.");
	    System.out.println("Properties jacorb.imr.ior_file and");
	    System.out.println("jacorb.ImplementationRepositoryURL");

	    System.exit(-1);
	}

	boolean _wait = true;
	
	if (args.length == 2){
	    if (args[1].equals("force"))
		_wait = false;
	    else {
		System.out.println("Unrecognized option: " + args[1]);
		usage();
	    }
	}
		
	try{
	    _admin.shutdown(_wait);
	    System.out.println("The Implementation Repository has been shut down correctly");
	}catch (Exception _e){
	    _e.printStackTrace();
	}
	System.exit(0);
    }
    
    /**
     * Set a server to not active.
     */    
    public static void setDown(String[] args){
	if (args.length < 2){
	    System.out.println("Please specify a server name");
	    usage();
	}

	Registration _reg = RegistrationHelper.narrow(ImplementationRepositoryImpl.getImR(m_orb));
	if (_reg == null){
	    System.out.println("Unable to connect to repository process!");
	    System.out.println("Please check, if the URL and the IOR file path point to the same file.");
	    System.out.println("Properties jacorb.imr.ior_file and");
	    System.out.println("jacorb.ImplementationRepositoryURL");

	    System.exit(-1);
	}
	
	try{
	    _reg.set_server_down(args[1]);
	    System.out.println("Server " + args[1] + " set down");
	}catch (Exception _e){
	    _e.printStackTrace();
	}
	System.exit(0);
    }



    /**
     * Print help messages.
     */
    public static void usage(){
	System.out.println("Usage: ImRManager <command> [<servername>] [switches]");
	System.out.println("Command: (add | edit) <servername> [-h hostname] [-c startup cmd]");
	System.out.println("\t -h <hostname> Use this hostname for the server");
	System.out.println("\t -c <command> Specifies a startup-command for this server");
	System.out.println("\t If -h is not set, the local hosts name is used");

	System.out.println("\nCommand: remove  (server | host) <name>");
	System.out.println("\t Removes the server or host  <name> from the repository");

	System.out.println("\nCommand: list (servers | hosts)");
	System.out.println("\t Lists all servers or all hosts");

	System.out.println("\nCommand: hold  <servername> [<time>]");
	System.out.println("\t Holds the server <servername> (if <time> is specified,");
	System.out.println("\t it is released automatically)");

	System.out.println("\nCommand: release  <servername>");
	System.out.println("\t Releases the server <servername>");

	System.out.println("\nCommand: setdown  <servername>");
	System.out.println("\t Declares the server <servername> as \"down\" to the repository,");
	System.out.println("\t that means the repository tries to start the server up after ");
	System.out.println("\t receiving the next request for it.");
	System.out.println("\t This is actually an operation only committed by the ORB, but it ");
	System.out.println("\t might be useful for server migration and recovery of crashed servers.");
	System.out.println("\t Note: Use \"hold\" before, to avoid the server being restarted at the");
	System.out.println("\t wrong moment.");

	System.out.println("\nCommand: savetable  ");
	System.out.println("\t Makes a backup of the server table");

	System.out.println("\nCommand: shutdown [force]");
	System.out.println("\t Shuts the ImR down orderly. If \"force\" is specified, the ORB ");
	System.out.println("\t is forced down, ignoring open connections.");

	System.out.println("\nCommand: gui");
	System.out.println("\t Bring up manager GUI window");

	System.out.println("\nCommand: help");
	System.out.println("\t This screen");

	System.exit(1);
    }

    /**
     * Main method.
     */
    public static void main(String[] args) {
	if( args.length == 0 )
	    usage();

        m_orb = (jacorb.orb.ORB) org.omg.CORBA.ORB.init(args, null);

	try{
	    if (args[0].equals("add") || args[0].equals("edit"))
		addServer(args);
	    else if (args[0].equals("remove"))
		remove(args);
	    else if (args[0].equals("list"))
		list(args);
	    else if (args[0].equals("hold"))
		holdServer(args);
	    else  if (args[0].equals("release"))
		releaseServer(args);
	    else  if (args[0].equals("savetable"))
		saveTable();
	    else  if (args[0].equals("shutdown"))
		shutdownImR(args);
	    else  if (args[0].equals("setdown"))
		setDown(args);
	    else  if (args[0].equals("gui"))
		new ImRManagerGUI();
	    else  if (args[0].equals("help"))
		usage();
	    else {
		System.out.println("Unrecognized command: " + args[0]);
		usage();
	    }
	}catch (Exception _e){
	    _e.printStackTrace();
	    System.exit(0);
	}
    }
    
} // ImRManager


