/**
 *
 * Object Server - generic object server for use in implementing servers.
 *
 * Author: Matthew W. Coan
 * Date: Tue Apr 24 16:57:34 EDT 2012
 *
 */
import java.io.*;
import java.net.*;
import java.util.*;

public class ObjectServer implements Runnable {
   public final static long MAX_THREAD_COUNT = 10;

   private String host = "localhost";
   private int port = 2012;
   private ThreadModel threadModel = null;

   public class RequestProcess implements Runnable {
      private Socket sock;
      private boolean error;
      private ObjectInputStream in = null;
      private ObjectOutputStream out = null;

      public RequestProcess(Socket s) { 
         sock = s;
         error = false;
      }

      public void run() {
System.out.println("PROCESS REQUEST...");
         try {
            if(in == null)
               in = new ObjectInputStream(new BufferedInputStream(sock.getInputStream()));

            if(out == null)
               out = new ObjectOutputStream(new BufferedOutputStream(sock.getOutputStream()));

            processRequest(in, out);

            //sock.close();
         }
         catch(Exception e) {
            e.printStackTrace(System.err);
            error = true;
         }
      } 
 
      public boolean getError() { 
         return error;
      }
   }

   public ObjectServer() {
      host = null;
      port = 1024;
      threadModel = new PerThreadModel();
   }

   public void setHost(String host) { this.host = host; }
   
   public void setPort(int port) { this.port = port; }

   public ObjectServer(String host, int port) {
      this.host = host;
      this.port = port;
      threadModel = new PerThreadModel();
   }

   public void setThread(String thModel) {
      try {
         Class clazz = Class.forName(thModel);

         threadModel = (ThreadModel)clazz.newInstance();
      }
      catch(Exception e) {
         e.printStackTrace(System.err);
      }
   }

   public void processRequest(ObjectInputStream in, 
                              ObjectOutputStream out)
   throws Exception {

   }

   public void run()  {
      ServerSocket svr = null;
      try {
         try {
            svr = new ServerSocket(port, 1024, InetAddress.getByName(host));
         }
         catch(Exception e) {
            svr = new ServerSocket(port, 1024, InetAddress.getByAddress(host.getBytes()));
         }

         Socket s;

         while((s = svr.accept()) != null) {
System.out.println("ACCEPT...");

            threadModel.runTask(new RequestProcess(s));
         }

         svr.close();
      }
      catch(Exception e) {
         e.printStackTrace(System.err);
      }
   }
   
   public static void main(String args[])   
   throws Exception {
      if(args.length != 4) {
         System.err.println("usage: ObjectServer <address> <port> <server_class> <thread_model>");

         System.exit(1);
      }

      ObjectServer server = (ObjectServer)(Class.forName(args[2]).newInstance());

      server.setHost(args[0]);

      server.setPort(Integer.parseInt(args[1]));

      server.setThread(args[3]);

      server.run();
   }
}

