// 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 = null;
        
        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 ;
		}
         
                java.rmi.activation.Activatable.exportObject( this, id, 0, ( java.rmi.server.RMIClientSocketFactory ) new mit.rmi.ClientSocketFactory()
		, ( java.rmi.server.RMIServerSocketFactory ) new mit.rmi.ServerSocketFactory()
		) ;
                
               //this.id = id;
              //run();
 //                new Thread(this).start();
		//System.out.println("Exported object = " + exportedObject);
	}

        
//         private final 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();
//                  throw new RuntimeException( ex.getLocalizedMessage() );
//              }
//                    System.out.println("Exported object = " + exportedObject);
//         }
//         
        private final String getClientHost() {
        //        return clientHost;
                //return exportedObject.getClientHost();
                // Probably wrong -- need to call the method below!!!
            try {
                return java.rmi.activation.Activatable.getClientHost();
            } catch ( Exception ex) {
                ex.printStackTrace();
            }
            return null;
         }
//        
	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" ;
	}

}
