package org.jcon.test.comm;

import org.jcon.ba.system.BeanActionStart;
import org.jcon.ba.system.BeanActionClose;
import org.jcon.util.GenLib;
import java.io.IOException;
import java.net.Socket;
import java.net.ServerSocket;

/**
 * This class is a server that enits sockets when
 * an accept() occurs. It is up to the CommServerUser
 * to validate the connection, such as waiting
 * for a UserID and Password.
 *
 * @author Jack Harich
 */
public class CommServer implements BeanActionStart,
        BeanActionClose, Runnable {

//---------- Private Fields ------------------------------
// Properties
private int            port;
private CommServerUser commServerUser;
// Internal
private ServerSocket   serverSocket;
private boolean        running;

//---------- BeanActionStart Implementation --------------
// Detect failure with isRunning()
public void start() {
    try {
        serverSocket = new ServerSocket(port);
        // Await connections
        running = true;
        new Thread(this).start();
        
    } catch(IOException ex) {
        GenLib.exception("CommServer.start()",
            "Failure while starting ServerSocket.", ex);        
    }        
}  
//---------- BeanActionClose Implementation --------------
public String canClose() {
    return null; // Yes ***
}
public void close() {
    try { 
        running = false;
        serverSocket.close(); // *** Will this work?
        serverSocket = null;
    } catch(IOException ex) {
        GenLib.exception("CommServer.close()",
            "Failure closing server.", ex);   
    }
}
//---------- Runnable Implementation ---------------------
public void run() { 
try {
    while(running) {
        print(" - awaiting client...");
        Socket clientSocket = serverSocket.accept();
        CommClient client = new CommClient();
        commServerUser.socketAccepted(clientSocket);
        print(" -   client accepted");
    }
} catch(IOException ex) {
    GenLib.exception("CommServer.run()",
        "Failure while awaiting connection.", ex);
}
} // End method
    
//---------- Properties ----------------------------------
//----- port
public void setPort(int port) {
    this.port = port;   
}    
public int getPort() {
    return port;   
} 
//----- commServerUser
public void setCommServerUser(CommServerUser user) {
    commServerUser = user;   
}    
//----- Other
public boolean isRunning() {
    return running;   
}    
//---------- Private Methods -----------------------------
//--- Std
private static void print(String text) {
    System.out.println("CommServer" + text);
}

} // End class
