/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

/*
 * Created on Jan 17, 2006
 */
package org.jboss.test.remoting.transport.multiplex;

import javax.management.MBeanServer;

import org.jboss.logging.Logger;
import org.jboss.remoting.Client;
import org.jboss.remoting.InvocationRequest;
import org.jboss.remoting.InvokerLocator;
import org.jboss.remoting.ServerInvocationHandler;
import org.jboss.remoting.ServerInvoker;
import org.jboss.remoting.callback.Callback;
import org.jboss.remoting.callback.HandleCallbackException;
import org.jboss.remoting.callback.InvokerCallbackHandler;
import org.jboss.remoting.transport.Connector;
import org.jboss.remoting.transport.PortUtil;
//import org.jboss.remoting.transport.multiplex.experimental.MultiplexTest;
import org.jboss.test.remoting.transport.multiplex.utility.SuccessCountingTestCase;

/**
* @author <a href="mailto:tim.fox@jboss.com">Tim Fox</a>
*
*/
public class MultipleClientTestCase extends SuccessCountingTestCase
{
  // Constants -----------------------------------------------------
  
  private static final Logger log = Logger.getLogger(MultipleClientTestCase.class);
  

  // Static --------------------------------------------------------
  
  // Attributes ----------------------------------------------------

  // Constructors --------------------------------------------------

  public MultipleClientTestCase(String name)
  {
     super(name);
  }

  // TestCase overrides -------------------------------------------

  public void setUp() throws Exception
  {

     super.setUp();
     
  }

  public void tearDown() throws Exception
  {
    
     super.tearDown();
  }

  
  public void testConnectionsRemainOpen() throws Throwable
  {
     //Start a server
     
     Connector serverConnector = new Connector();
     InvokerLocator serverLocator = new InvokerLocator("multiplex://localhost:9099");
     serverConnector.setInvokerLocator(serverLocator.getLocatorURI());
     serverConnector.create();
     SimpleServerInvocationHandler invocationHandler = new SimpleServerInvocationHandler();
     serverConnector.addInvocationHandler("JMS", invocationHandler);
     serverConnector.start(); 
     
     log.info("Server started");
     
     for (int i = 0; i < 5; i++)
     {
        
        //Create a client for invoking on the server:
        
        int localPort = PortUtil.findFreePort("localhost");
        
        log.info("Free port is:" + localPort);
                 
        String locatorURI = "multiplex://localhost:9099/?clientMultiplexId=mytestid&multiplexBindHost=localhost&multiplexBindPort=" + localPort;
        InvokerLocator locatorClient = new InvokerLocator(locatorURI);
        Client client = new Client(locatorClient);
        
        log.info("Created client");
              
        Connector callbackServerConnector = new Connector();      
        
        InvokerLocator callbackServerLocator = new InvokerLocator("multiplex://localhost:" + localPort + "/?serverMultiplexId=mytestid");
        
        callbackServerConnector.setInvokerLocator(callbackServerLocator.getLocatorURI());      
        callbackServerConnector.create();      
        callbackServerConnector.start();
        
        log.info("Created callback server");
        
        client.connect();
        
        log.info("Connected client");
        
        //REMOTING HANGS ON THIS INVOCATION
        
        log.info("Invoking");
        
        String response = (String)client.invoke("Cheese");
        
        log.info("Invocation completed");
        
        assertNotNull(response);
        assertEquals("Sausages", response);
        
        SimpleCallbackHandler callbackHandler = new SimpleCallbackHandler();
        
        client.addListener(callbackHandler, callbackServerLocator);
        
        assertNotNull(invocationHandler.handler);
        
        Callback cb = new Callback("Squirrel");
        
        invocationHandler.handler.handleCallback(cb);
        
        assertNotNull(callbackHandler.callback);
        assertEquals("Squirrel", callbackHandler.callback.getParameter());
        
        callbackServerConnector.stop();
        
        client.disconnect();
       
     }
     
//     Thread.sleep(1000 * 60 * 30);
     
     //Now run netstat -a and see how many TCP connections are open!
     
     log.info("testConnectionsRemainOpen() PASSES");
     OKCounter++;
  }

  class SimpleCallbackHandler implements InvokerCallbackHandler
  {
     
     Callback callback;

     public void handleCallback(Callback callback) throws HandleCallbackException
     {
        this.callback = callback;         
     }
     
  }
  
  class SimpleServerInvocationHandler implements ServerInvocationHandler
  {
     InvokerCallbackHandler handler;
     
     
     public void addListener(InvokerCallbackHandler callbackHandler)
     {
        this.handler = callbackHandler;
        
     }

     public Object invoke(InvocationRequest invocation) throws Throwable
     {
        log.info("Received invocation:" + invocation);
        
        return "Sausages";
     }

     public void removeListener(InvokerCallbackHandler callbackHandler)
     {
        // FIXME removeListener
        
     }

     public void setInvoker(ServerInvoker invoker)
     {
        // FIXME setInvoker
        
     }

     public void setMBeanServer(MBeanServer server)
     {
        // FIXME setMBeanServer
        
     }
     
  }
  
}