//   Course Number: COSC 645 Applied Cryptography
//    Program Name: ServerExecThread
//         Authors: Brian Hoffman
//                  Derek Waby
//                  Kypros Ioannou
//                  Harsha V. Reddy          
//     Description: In short, this class extends thread and is responsible for 
//                  maintaining the loop that accepts connections from clients, 
//                  constructs a ServerConnection object, and uses that object
//                  to spawn a ClientThread that listens to that connection. This
//                  functionality is exectued as a separate thread because the 
//                  server is launched upon an action event and running the code
//                  within the event handler would lock up the GUI. This class 
//                  frees the event-thread to perform GUI updates and puts all 
//                  the work into a separate chain of execution that can be stoped
//                  when desired.

// Java Core Packages
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

// Jave Extension Packages 
import javax.swing.*;

public class ServerExecThread extends Thread
{
    public static final int PORT_NUM = 4567;
    private ServerSocket serverSocket;
    private ShamirServer myServer;
  
    /**
     * ------------------------------------------------------------------------
     * Constructor - sets the server with whom this thread is associated and 
     *               whose methods will be used to handle the actual processing
     *               of messages
     * ------------------------------------------------------------------------
     */
    public ServerExecThread(ShamirServer inServer)
    {
        myServer = inServer;
    }
    
    /**
     * ------------------------------------------------------------------------
     * run - overridden method of the thread class that executes the task to 
     *       be performed by the thread. In this case, the thread listens to 
     *       input messages and dipatches them to the proper methods of the 
     *       ShamirServer class.
     * ------------------------------------------------------------------------
     */    
    public void run()
    {
        // start listening for socket connections
        try
        {
            serverSocket = new ServerSocket(PORT_NUM, 100);
            serverSocket.setSoTimeout(500);
            myServer.postOutput( "Server listening on port " +
                                 Integer.toString(PORT_NUM) + "..."); 
            
            while (!interrupted())
            {
                // accept a new client connection 
                Socket clientSocket;
                try
                { clientSocket = serverSocket.accept(); }
                catch(SocketTimeoutException ste)
                { continue; }
                ServerConnection connection = new ServerConnection(clientSocket);
                myServer.postOutput("Connected to " + clientSocket.getInetAddress()); 
            
                // create a new thread to deal with it
                ClientThread currentClient = new ClientThread(myServer, connection);
                myServer.addClient(currentClient);
                currentClient.start();
            }
        }
        
        // deal with problems creating the server socket
        catch (IOException ioException)
        {
           JOptionPane.showMessageDialog(null,"Could not create server socket. \n" +
                        "Press End Server button to restart","Server socket Error",
                        JOptionPane.ERROR_MESSAGE);
           ioException.printStackTrace();
        }
        
        // no matter what close the socket 
        finally
        {
           try
           {
               myServer.cleanClients();
               serverSocket.close();
           }
           catch (Exception e) {return; }
        }
    } 
}