// worry: probably don't want to require mit.krb4.Authenticate for this

// try this without extending Activatable
package mit.rmi ;

public class Server
//extends java.rmi.activation.Activatable
implements mit.rmi.Interface
{
	protected String service = null ;
	protected transient byte[] srvtab = null ;
	protected transient boolean isAuthenticated = true ;
	protected String tag = null ;
        
        private java.rmi.Remote exportedObject;
        private final String clientHost = java.rmi.activation.Activatable.getClientHost();
        private java.rmi.activation.ActivationID id;
	public Server( final java.rmi.activation.ActivationID id , final java.rmi.MarshalledObject data )
	throws Exception
	{
		//super
		//( id
		//, 0
		//, ( java.rmi.server.RMIClientSocketFactory ) new mit.rmi.ClientSocketFactory()
		//, ( java.rmi.server.RMIServerSocketFactory ) new mit.rmi.ServerSocketFactory()
		//) ;
		srvtab = ( byte[] ) data.get() ;
		System.out.println( "DEBUG: in Server( java.rmi.activation.ActivationID " + id + ", java.rmi.MarshalledObject      " + data + ") -- srvtab = " + new String(srvtab) );

		if( null != srvtab )
		{
			isAuthenticated = false ;
		}
                this.id = id;
                run();
                //new Thread(this).start();
		//System.out.println("Exported object = " + exportedObject);
	}

        
         private void run() {
		//java.rmi.Remote exportedObject = 
              try {
                java.rmi.activation.Activatable.exportObject( this, id, 0, ( java.rmi.server.RMIClientSocketFactory ) new mit.rmi.ClientSocketFactory()
		, ( java.rmi.server.RMIServerSocketFactory ) new mit.rmi.ServerSocketFactory()
		) ;
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
                    System.out.println("Exported object = " + exportedObject);
         }
         
        private final String getClientHost() {
                return clientHost;
                //return exportedObject.getClientHost();
                // Probably wrong -- need to call the method below!!!
                //return java.rmi.activation.Activatable.getClientHost();
        }
        
	public Boolean authenticate( byte[] ticket )
	{       
            System.out.println("In authenticate( byte[] ticket at " + new java.util.Date() );
		try
		{
			mit.krb4.Authenticate authenticate = new mit.krb4.Authenticate() ;
			byte[] clientAddress = java.net.InetAddress.getByName( getClientHost() ).getAddress() ;
			String host = java.net.InetAddress.getLocalHost().getHostName() ;
			this.tag = authenticate.isValidClient( ticket , clientAddress , srvtab ) ;
			// GS
			
			System.out.println( "In authenticate ticket = " + new String(ticket) + ", from client " +  getClientHost() );
			System.out.println( "Client address = " + new String(clientAddress) );
			System.out.println( "srvtab = " + new String(srvtab) );
			System.out.println( "Tag = " + tag );
			System.out.flush();
			mit.util.ThreadContext.setProperty( "Tag" , this.tag ) ;
			isAuthenticated = true ;
			return new Boolean( true ) ;
		}
		catch( Throwable ex )
		{
		}
		return new Boolean( false ) ;
	}

	public Object invoke( java.io.Serializable object , String methodName , Class[] argTypes , Object[] args )
	{
            Object response = null ;
		try
		{
			if( isAuthenticated )
			{
				java.lang.reflect.Method method = null ;
				if( ! ( object instanceof java.lang.Class ) )
				{
					method = object.getClass().getMethod( methodName , argTypes ) ;
				}
				else
				{
					method = ( ( Class ) object ).getMethod( methodName , argTypes ) ;
				}
				response = method.invoke( object , args ) ;
			}
			else
			{
				response = new mit.rmi.AuthenticateException() ;
			}
		}
		catch( Throwable ex )
		{
			response = ex ;
		}
		return response ;
	}

	public String test()
	{
		return "Test successful" ;
	}

}