import java.io.*;
import java.net.*;
import java.util.*;


/**
 * A simple skeleton for a database of Course objects.
 *
 * Note: This approach does not use a registry.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class CourseDatabaseSkeleton implements Runnable
{
    private int                     port;
    private Thread                  controlThread;
    private CourseDatabase          implementation;
    private ObjectInputStream       in;
    private ObjectOutputStream      out;

    /**
     * Constructor
     */
    public CourseDatabaseSkeleton(CourseDatabase  implementation,
				  int             port)
    {
       this.implementation = implementation;
       this.port = port;
    }

    /**
     * Add a Course
     */
    public void add() throws ClassNotFoundException, IOException
    {
       Course    course;

       // Get arguments from the stub
       course = (Course)in.readObject();

       // Make the call to the implementation
       implementation.add(course);
    }

    /**
     * Get a Course
     */
    public void get()  throws ClassNotFoundException, IOException
    {
       Course     course;
       int        number;
       String     department;


       // Get arguments from the stub
       department = (String)in.readObject();
       number     = in.readInt();

       // Make the call to the implementation
       course = implementation.get(department, number);

       // Return course to the stub
       out.writeObject(course);
       out.flush();
    }

    /**
     * Read a method invocation from the stub
     */
    public void readFromStub()
    {
       String    method;

       try 
       {
          method = (String)in.readObject();
          if (method.equals("add"))         add();
          else if (method.equals("get"))    get();
          else if (method.equals("remove")) remove();

       } 
       catch (IOException ioe) 
       {
          // Ignore
       } 
       catch (ClassNotFoundException cnfe) 
       {
          // Ignore
       }
    }

    /**
     * Remove a Course
     */
    public void remove()  throws ClassNotFoundException, IOException
    {
       int        number;
       String     department;

       // Get arguments from the stub
       department = (String)in.readObject();
       number     = in.readInt();

       // Make the call to the implementation
       implementation.remove(department, number);
    }


    /**
     * Entry point for the thread
     */
    public void run()
    {
       ServerSocket      ss;
       Socket            s;


       try 
       {
          ss = new ServerSocket(port);
          s = ss.accept();

          in  = new ObjectInputStream(s.getInputStream());
          out = new ObjectOutputStream(s.getOutputStream());

          while (true) 
          {
             readFromStub();
          }
       } 
       catch (IOException ioe) 
       {
          ioe.printStackTrace();
       }
    }

    /**
     * Start this skeleton.
     */
    public void start()
    {
        if (controlThread == null)
        {
            controlThread = new Thread(this);
            controlThread.start();
        }
    }
    
}
