/* IMPORTS */
import java.io.*;
import java.net.*;
import Message;
import ServerServer;
import TerminalServer;
import RoomListener;
import ServerListener;

public class ChatServer extends Thread
{
    /* CONSTANTS */
    // NONE

    /* MEMBER VARIABLES */
    int terminal_port;      // Port number of terminal server
    int server_port;        // Port number of server server
    String server_name;     // Name of server server
    int server_ID;          // ID of server server
    ServerListener SrvSrv;  // ServerListener for server server
    RoomListener TrmSrv;    // RoomListener for terminal server

    public ChatServer()
    {
        /* USE DEFAULT VALUES */
        terminal_port = 9009;
        server_port = 9010;    
        server_name = "Main Server";
        server_ID = 0;

        start(); // Calls run method
    } // constructor

    public ChatServer(int trm_port, int srv_port, String name, int srv_ID)
    {
        /* USE SPECIFIED VALUES */
        terminal_port = trm_port;
        server_port = srv_port;
        server_name = name;
        server_ID = srv_ID;
        
        start(); // Calls run method
    } // constructor
    
    public static void main(String args[])
    {
        /* LOCAL VARIABLES */
        int port1;    // Temporary port number for terminal server
        int port2;    // Temporary port number for server server
        String name;  // Temporary name for server server
        int ID;       // Temporary ID for server server
        
        /* CHECK ARGUMENTS */
        // => ALL SUPPLIED
        if(args.length == 4)
        {
            port1 = Integer.parseInt(args[0]);
            port2 = Integer.parseInt(args[1]);
            name = args[2];
            ID    = Integer.parseInt(args[3]);

            new ChatServer(port1,port2,name,ID);
        } // if
        // => NONE SUPPLIED
        else if (args.length == 0)
        {
            new ChatServer();
        } // else if
        // => OTHERWISE
        else
        {
           System.out.println("An incorrect number of arguments were supplied.  The correct format is:\n"+
                              " java ChatServer [<terminal port> <server port> <server name> <server ID>]\n");
        } // else
    } // method main
  
    public void run()
    {
        /* LOCAL VARIABLES */
        String command = "";  // String for user's commands
        String response;      // String for user's respones
        boolean valid;        // Validity of user's responses
        String IP_address;    // Temporary IP Address for additional server server
        int port;             // Temporary port number for additional server
        String name;          // Temporary name for server server
        int ID;               // Temporary ID for server server
        Socket skt;           // Temporary socket for additional server server

        /* STANDARD TEXT INPUT STREAM SETUP */
        BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in) );

        /* START CHAT SERVER */
        System.out.print(" \n"+
                         " ----------------------------------------------\n"+
                         "   Welcome to the Cluster Chat Server System   \n"+
                         "               Version 1.0 BETA                \n"+
                         "  Created by Jon Schlueter and B. Alex Bridges \n"+
                         "           Date of Birth: 09/19/199            \n"+
                         "   ECE-488 Computer Networks - Final Project   \n"+
                         " ----------------------------------------------\n"+
                         " \n");
        
        System.out.println("Chat server '"+server_name+"' ID '"+server_ID+"' coming online . . . \n");
        
        // => INITIAL SERVER SERVER
        System.out.print(" Server server coming online . . . ");
        SrvSrv = (ServerListener) new ServerServer(server_port,server_name,server_ID);
        System.out.println("now online at port "+server_port+".");
        
        // => INITIAL TERMINAL SERVER
        System.out.print(" Terminal server coming online . . . ");
        TrmSrv = (RoomListener) new TerminalServer(terminal_port);
        System.out.println("now online at port "+terminal_port+".");

        // => APPLY LISTENERS TO SERVERS
        TrmSrv.addServerListener(SrvSrv);
        SrvSrv.addRoomListener(TrmSrv);

        System.out.println("\nChat server now online.\n");

        System.out.println("Ready to accept commands and process requests.\n"+
                           "Type \"help\" for a list of supported commands.\n");

        /* HANDLING OF COMMANDS */
        while(true)
        {
            try
            {
                // => GET THE COMMAND
                command = stdin.readLine();
                                
                // => HELP COMMAND
                if( command.toLowerCase().startsWith("help") )
                {
                    System.out.println("The following commands are supported at this time:\n"+
                                       " -> help    = Prints this menu.\n"+
                                       " -> add     = Adds another server node for use by the chat server.\n"+
                                       " -> cleanup = Forces a cleanup of the lists on the server.\n"+
                                       " -> status  = Prints the currrent status of chat server.\n"+
                                       " -> quit    = Stops the chat server and all associated servers.\n"+
                                       " -> exit    = Also stops the chat server and all associated servers.\n");

                } // if
                // => ADD COMMAND
                else if( command.toLowerCase().startsWith("add") )
                {
                    do
                    {
                        System.out.print("Are you sure that you wish to add another server node? ('y' -or- 'n') ");
                        response = stdin.readLine();
                        if( response.toLowerCase().startsWith("y") || response.toLowerCase().startsWith("n") )
                            valid = true;
                        else
                            valid = false;
                    } while(!valid);
                                       
                    if( response.toLowerCase().startsWith("y") )
                    {
                        System.out.print("Enter its IP address: ");
                        IP_address = stdin.readLine();
                        
                        System.out.print("Enter port for connection to an exisiting server server: ");
                        port = Integer.parseInt( stdin.readLine() );
                        
                        System.out.println();
                        
                        skt = new Socket(InetAddress.getByName(IP_address),port);
                        ((ServerServer)SrvSrv).add(skt);
                        
                    } // if
                } // else if
                // => CLEANUP COMMAND
                else if( command.toLowerCase().startsWith("cleanup") )
                {
                    System.out.print("Cleaning up . . . ");
                    SrvSrv.cleanup();
                    TrmSrv.cleanup();
                    System.out.println("completed.\n");
                } // else if
                // => STATUS COMMAND
                else if( command.toLowerCase().startsWith("status") )
                {
                    System.out.println("Chat Server's Status:\n"+
                                       " -> Name of initial server server: '"+server_name+"'\n"+
                                       " -> ID of initial server server:   '"+server_ID+"'\n"+
                                       " -> Port of initial server server: '"+server_port+"'\n"+
                                       " -> Port of initial terminal server: '"+terminal_port+"'\n");
                    SrvSrv.status();
                    TrmSrv.status();
                } // else if
                // => QUIT/EXIT COMMAND
                else if( command.toLowerCase().startsWith("quit") || command.toLowerCase().startsWith("exit") )
                {
                    do
                    {
                        System.out.print("Are you sure that you wish to stop the chat server? ('y' -or- 'n') ");
                        response = stdin.readLine();
                        if( response.toLowerCase().startsWith("y") || response.toLowerCase().startsWith("n") )
                            valid = true;
                        else
                            valid = false;
                    } while(!valid);
                    
                    if( response.toLowerCase().startsWith("y") )
                        break;
                    
                    System.out.println();
                } // else if
            } // try
            catch(ConnectException e)
            {
                System.err.println("ConnectException has occurred.  The exception was:\n"+
                                   e+"\n");
                e.printStackTrace(System.err);
            } // catch exception
            catch(NumberFormatException e)
            {
                System.err.println("NumberFormatException has occurred.  The exception was:\n"+
                                   e+"\n");
                e.printStackTrace(System.err);
            } // catch exception
            catch(IOException e)
            {
                System.err.println("IOException has occurred.  The exception was:\n"+
                                   e+"\n");
                e.printStackTrace(System.err);
            } // catch exception
            
            yield();
        } // while
        
        // NOTE: THIS NEEDS TO BE FIXED SO THAT ALL CURRENT THREADS ARE PROPERLY KILLED!
        System.out.println("\nChat server shutting down . . . \n");
        System.exit(0);
    } // method run
} // class ChatServer
