// The Threaded Handle connection class - that deals will all client requests directly
// by Derek Molloy

import java.net.*;
import java.io.*;
import java.util.*;


public class ThreadedHandleConnection extends Thread
{

    private Socket clientSocket;			// Client socket object
    private ObjectInputStream is;			// Input stream
    private ObjectOutputStream os;			// Output stream
    private DateTimeService theDateService;
    
    // The constructor for the connecton handler

    public ThreadedHandleConnection(Socket clientSocket) 
    {
        this.clientSocket = clientSocket;

        //Set up a service object to get the current date and time
        theDateService = new DateTimeService();
    }

    // The main thread execution method 

    public void run() 
    {
        String inputLine;

        try 
        {
            this.is = new ObjectInputStream(clientSocket.getInputStream());
            this.os = new ObjectOutputStream(clientSocket.getOutputStream());
            while (this.readCommand()) {}

         } 
         catch (IOException e) 
         {
                e.printStackTrace();
         }
    }

    // Receive and process incoming command from client socket 

    private boolean readCommand() 
    {
        String s = null;

        try 
        {
            s = (String)is.readObject();
        } 
        catch (Exception e) 
        {
            s = null;
        }
        if (s == null) 
        {
            this.closeSocket();
            return false;
        }

        // invoke the appropriate function based on the command 
        if (s.equals("GetDate")) 
        { 
            this.getDate(); 
        }       
        else 
        { 
            this.sendError("Invalid command: " + s); 
        }
        return true;
    }

    private void getDate()	// uses the date service to get the date
    {        
        String currentDateTime = theDateService.getDateAndTime();
        this.send(currentDateTime);
    }


    // Send a message back through to the client socket as an Object
    private void send(Object o) 
    {
        try 
        {
            System.out.println("Sending " + o);
            this.os.writeObject(o);
            this.os.flush();
        } 
        catch (Exception ex) 
        {
            ex.printStackTrace();
        }
    }
    
    // Send a pre-formatted error message to the client 
    public void sendError(String msg) 
    {
        this.send("error:" + msg);	//remember a string IS-A object!
    }
    
    // Close the client socket 
    public void closeSocket()		//close the socket connection
    {
        try 
        {
            this.os.close();
            this.is.close();
            this.clientSocket.close();
        } 
        catch (Exception ex) 
        {
            System.err.println(ex.toString());
        }
    }

}
