/*
 * LunchServerSocketProxy
 *
 * A proxy to support access to the service through the service defined
 * wire protocol.
 *
 * Author: Brian Jeltema
 */

import java.rmi.*;
import java.io.Serializable ;
import java.io.* ;
import java.util.Hashtable;
import java.net.* ;
import net.jini.core.event.* ;

public class LunchServerSocketProxy implements LunchCoordinator,Serializable {


    public final static int REGISTER = 1 ;
    public final static int CHANGE   = 2 ;
    public final static int GET      = 3 ;
    public final static int CLEAR    = 4 ;
    public final static int DUMP     = 5 ;
    public final static int EVENTREG = 6 ;

    int port ;
    InetAddress addr ;
    transient Socket socket ;
    transient ObjectInputStream is ;
    transient ObjectOutputStream os ;

    public LunchServerSocketProxy(InetAddress addr,int port) {
        this.addr = addr ;
        this.port = port ;
    }

    private void readObject(ObjectInputStream stream) throws IOException,ClassNotFoundException {
	stream.defaultReadObject() ;
	try {
	    socket = new Socket(addr,port) ;
	    os = new ObjectOutputStream(socket.getOutputStream()) ;
            os.flush() ;
	    is = new ObjectInputStream(socket.getInputStream()) ;
	}
	catch (Exception e) {
	    System.out.println("exception in readObject: " + e) ;
            e.printStackTrace() ;
	}
    }

    public synchronized void registerPref(String name, String food) throws RemoteException {
        System.out.println("Socket registerPref") ;
	try {
	    os.writeInt(REGISTER) ;
	    os.writeUTF(name) ;
	    os.writeUTF(food) ;
	    os.flush() ;
	}
	catch (Exception e) {
	    System.out.println("exception in registerPref: " + e) ;
            e.printStackTrace() ;
	}
    }

    public synchronized void changePref(String name, String food) throws RemoteException {
        System.out.println("Socket changePref") ;
	try {
	    os.writeInt(CHANGE) ;
	    os.writeUTF(name) ;
	    os.writeUTF(food) ;
	    os.flush() ;
	}
	catch (Exception e) {
	    System.out.println("exception in changePref: " + e) ;
            e.printStackTrace() ;
	}
    }

    public synchronized Hashtable getLunchers() throws RemoteException {
        System.out.println("Socket getLunchers") ;
	Hashtable ht = new Hashtable() ;
	try {
	    os.writeInt(GET) ;
	    os.flush() ;
	    for (int count = is.readInt() ; --count>=0 ;)
		ht.put(is.readUTF(),is.readUTF()) ;
	}
	catch (Exception e) {
	    System.out.println("exception in getLunchers: " + e) ;
            e.printStackTrace() ;
	}
	return ht ;
    }

    public synchronized void clearServer() throws RemoteException {
        System.out.println("Socket clearServer") ;
	try {
	    os.writeInt(CLEAR) ;
	    os.flush() ;
	}
	catch (Exception e) {
	    System.out.println("exception in clearServer: " + e) ;
            e.printStackTrace() ;
	}
    }

    public synchronized void dump() throws RemoteException {
        System.out.println("Socket dump") ;
	try {
	    os.writeInt(DUMP) ;
	    os.flush() ;
	}
	catch (Exception e) {
	    System.out.println("exception in dump: " + e) ;
            e.printStackTrace() ;
	}
    }

    public synchronized EventRegistration registerListener(RemoteEventListener l,long duration) throws RemoteException {
        System.out.println("Socket register listener") ;
        try {
            os.writeInt(EVENTREG) ;
            os.writeObject(new MarshalledObject(l)) ;
            os.writeLong(duration) ;
            os.flush() ;
            MarshalledObject reg = (MarshalledObject)is.readObject() ;
            return (EventRegistration)reg.get() ;
	}
	catch (Exception e) {
	    System.out.println("exception in registerListener: " + e) ;
            e.printStackTrace() ;
	}
        return null ; 
    }
}
