/**
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.apache.geronimo.connector.outbound.connectiontracking;

import junit.framework.TestCase;
import org.apache.geronimo.connector.outbound.ConnectionInterceptor;
import org.apache.geronimo.connector.outbound.ConnectionTrackingInterceptor;
import org.apache.geronimo.connector.outbound.ConnectionInfo;
import org.apache.geronimo.connector.outbound.ConnectionReturnAction;
import org.apache.geronimo.connector.outbound.ManagedConnectionInfo;
import org.apache.geronimo.connector.outbound.GeronimoConnectionEventListener;

import javax.security.auth.Subject;
import javax.resource.ResourceException;
import javax.resource.spi.ManagedConnection;
import javax.resource.spi.ConnectionRequestInfo;
import javax.resource.spi.ConnectionEventListener;
import javax.resource.spi.LocalTransaction;
import javax.resource.spi.ManagedConnectionMetaData;
import javax.transaction.xa.XAResource;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.lang.reflect.Proxy;
import java.io.PrintWriter;

/**
 * @version $Rev: 476049 $ $Date: 2006-11-16 20:35:17 -0800 (Thu, 16 Nov 2006) $
 */
public class ConnectionTrackingCoordinatorProxyTest extends TestCase implements ConnectionInterceptor {
    private static final String name1 = "foo";
    private ConnectionTrackingCoordinator connectionTrackingCoordinator;
    private ConnectionTrackingInterceptor key1;
    private Subject subject = null;
    private Set<String> unshareableResources;
    private Set<String> applicationManagedSecurityResources;
    private ManagedConnectionInfo mci;
    private ConnectionImpl connection;

    protected void setUp() throws Exception {
        super.setUp();
        connectionTrackingCoordinator = new ConnectionTrackingCoordinator(true);
        key1 = new ConnectionTrackingInterceptor(this, name1, connectionTrackingCoordinator);
        unshareableResources = new HashSet<String>();
        applicationManagedSecurityResources = new HashSet<String>();

        mci = new ManagedConnectionInfo(null, null);
        mci.setManagedConnection(new MockManagedConnection());
        mci.setConnectionEventListener(new GeronimoConnectionEventListener(this, mci));
        connection = new ConnectionImpl("ConnectionString");
    }

    protected void tearDown() throws Exception {
        connectionTrackingCoordinator = null;
        key1 = null;
        super.tearDown();
    }

    public void testSimpleComponentContextLifecyle() throws Exception {
        // enter component context
        ConnectorInstanceContextImpl componentContext = new ConnectorInstanceContextImpl(unshareableResources, applicationManagedSecurityResources);
        ConnectorInstanceContext oldConnectorInstanceContext = connectionTrackingCoordinator.enter(componentContext);
        assertNull("Expected old instance context to be null", oldConnectorInstanceContext);

        // simulate create connection
        ConnectionInfo connectionInfo = createConnectionInfo();
        connectionTrackingCoordinator.handleObtained(key1, connectionInfo, false);

        // connection should be in component instance context
        Map<ConnectionTrackingInterceptor, Set<ConnectionInfo>> connectionManagerMap = componentContext.getConnectionManagerMap();
        Set<ConnectionInfo> infos = connectionManagerMap.get(key1);
        assertNotNull("Expected one connections for key1", infos);
        assertEquals("Expected one connection for key1", 1, infos.size());
        assertTrue("Expected to get supplied ConnectionInfo from infos", connectionInfo == infos.iterator().next());

        // verify handle
        Object handle = connectionInfo.getConnectionHandle();
        assertNotNull("Expected a handle from ConnectionInfo", handle);
        assertTrue("Expected handle to be an instance of ConnectionImpl", handle instanceof ConnectionImpl);
        ConnectionImpl connection = (ConnectionImpl) handle;
        assertEquals("connection.getString()", "ConnectionString", connection.getString());

        // verify proxy
        Object proxy = connectionInfo.getConnectionProxy();
        assertNotNull("Expected a proxy from ConnectionInfo", proxy);
        assertTrue("Expected proxy to be an instance of Connection", proxy instanceof Connection);
        Connection connectionProxy = (Connection) proxy;
        assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
        assertSame("Expected connection.getUnmanaged() to be connectionImpl", connection, connectionProxy.getUnmanaged());
        assertNotSame("Expected connection be proxied", connection, connectionProxy);

        // exit component context
        connectionTrackingCoordinator.exit(oldConnectorInstanceContext);

        // connection should not be in context
        connectionManagerMap = componentContext.getConnectionManagerMap();
        infos = connectionManagerMap.get(key1);
        assertEquals("Expected no connection set for key1", null, infos);

        // enter again, and close the handle
        oldConnectorInstanceContext = connectionTrackingCoordinator.enter(componentContext);
        assertNull("Expected old instance context to be null", oldConnectorInstanceContext);
        connectionTrackingCoordinator.handleReleased(key1, connectionInfo, ConnectionReturnAction.DESTROY);
        connectionTrackingCoordinator.exit(oldConnectorInstanceContext);

        // use connection which will cause it to get a new handle if it is not closed
        ConnectionTrackingCoordinator.ConnectionInvocationHandler invocationHandler = (ConnectionTrackingCoordinator.ConnectionInvocationHandler) Proxy.getInvocationHandler(connectionProxy);
        assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
        assertTrue("Proxy should be connected", invocationHandler.isReleased());
        assertSame("Expected connection.getUnmanaged() to be original connection", connection, connection.getUnmanaged());
    }

    public void testReassociateConnection() throws Exception {
        // enter component context
        ConnectorInstanceContextImpl componentContext = new ConnectorInstanceContextImpl(unshareableResources, applicationManagedSecurityResources);
        ConnectorInstanceContext oldConnectorInstanceContext1 = connectionTrackingCoordinator.enter(componentContext);
        assertNull("Expected old component context to be null", oldConnectorInstanceContext1);

        // simulate create connection
        ConnectionInfo connectionInfo = createConnectionInfo();
        connectionTrackingCoordinator.handleObtained(key1, connectionInfo, false);

        // connection should be in component instance context
        Map<ConnectionTrackingInterceptor, Set<ConnectionInfo>> connectionManagerMap = componentContext.getConnectionManagerMap();
        Set<ConnectionInfo> infos = connectionManagerMap.get(key1);
        assertNotNull("Expected one connections for key1", infos);
        assertEquals("Expected one connection for key1", 1, infos.size());
        assertTrue("Expected to get supplied ConnectionInfo from infos", connectionInfo == infos.iterator().next());

        // verify handle
        Object handle = connectionInfo.getConnectionHandle();
        assertNotNull("Expected a handle from ConnectionInfo", handle);
        assertTrue("Expected handle to be an instance of ConnectionImpl", handle instanceof ConnectionImpl);
        ConnectionImpl connection = (ConnectionImpl) handle;
        assertEquals("connection.getString()", "ConnectionString", connection.getString());

        // verify proxy
        Object proxy = connectionInfo.getConnectionProxy();
        assertNotNull("Expected a proxy from ConnectionInfo", proxy);
        assertTrue("Expected proxy to be an instance of Connection", proxy instanceof Connection);
        Connection connectionProxy = (Connection) proxy;
        assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
        assertSame("Expected connection.getUnmanaged() to be connectionImpl", connection, connectionProxy.getUnmanaged());
        assertNotSame("Expected connection be proxied", connection, connectionProxy);


        // exit outer component context
        connectionTrackingCoordinator.exit(oldConnectorInstanceContext1);

        // proxy should be disconnected
        ConnectionTrackingCoordinator.ConnectionInvocationHandler invocationHandler = (ConnectionTrackingCoordinator.ConnectionInvocationHandler) Proxy.getInvocationHandler(connectionProxy);
        assertTrue("Proxy should be disconnected", invocationHandler.isReleased());

        // enter again
        oldConnectorInstanceContext1 = connectionTrackingCoordinator.enter(componentContext);
        assertNull("Expected old component context to be null", oldConnectorInstanceContext1);

        // use connection to cause it to get a new handle
        assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
        assertSame("Expected connection.getUnmanaged() to be original connection", connection, connection.getUnmanaged());
        assertNotSame("Expected connection to not be original connection", connection, connectionProxy);

        // destroy handle and exit context
        connectionTrackingCoordinator.handleReleased(key1, connectionInfo, ConnectionReturnAction.DESTROY);
        connectionTrackingCoordinator.exit(oldConnectorInstanceContext1);

        // connection should not be in context
        connectionManagerMap = componentContext.getConnectionManagerMap();
        infos = connectionManagerMap.get(key1);
        assertNull("Expected no connection set for key1", infos);

        // use connection which will cause it to get a new handle if it is not closed
        assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
        assertTrue("Proxy should be connected", invocationHandler.isReleased());
        assertSame("Expected connection.getUnmanaged() to be original connection", connection, connection.getUnmanaged());

    }

    // some code calls the release method using a freshly constructed ContainerInfo without a proxy
    // the ConnectionTrackingCoordinator must find the correct proxy and call releaseHandle or destroy
    public void testReleaseNoProxy() throws Exception {
        // enter component context
        ConnectorInstanceContextImpl componentContext = new ConnectorInstanceContextImpl(unshareableResources, applicationManagedSecurityResources);
        ConnectorInstanceContext oldConnectorInstanceContext1 = connectionTrackingCoordinator.enter(componentContext);
        assertNull("Expected old component context to be null", oldConnectorInstanceContext1);

        // simulate create connection
        ConnectionInfo connectionInfo = createConnectionInfo();
        connectionTrackingCoordinator.handleObtained(key1, connectionInfo, false);

        // connection should be in component instance context
        Map<ConnectionTrackingInterceptor, Set<ConnectionInfo>> connectionManagerMap = componentContext.getConnectionManagerMap();
        Set<ConnectionInfo> infos = connectionManagerMap.get(key1);
        assertNotNull("Expected one connections for key1", infos);
        assertEquals("Expected one connection for key1", 1, infos.size());
        assertTrue("Expected to get supplied ConnectionInfo from infos", connectionInfo == infos.iterator().next());

        // verify handle
        Object handle = connectionInfo.getConnectionHandle();
        assertNotNull("Expected a handle from ConnectionInfo", handle);
        assertTrue("Expected handle to be an instance of ConnectionImpl", handle instanceof ConnectionImpl);
        ConnectionImpl connection = (ConnectionImpl) handle;
        assertEquals("connection.getString()", "ConnectionString", connection.getString());

        // verify proxy
        Object proxy = connectionInfo.getConnectionProxy();
        assertNotNull("Expected a proxy from ConnectionInfo", proxy);
        assertTrue("Expected proxy to be an instance of Connection", proxy instanceof Connection);
        Connection connectionProxy = (Connection) proxy;
        assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
        assertSame("Expected connection.getUnmanaged() to be connectionImpl", connection, connectionProxy.getUnmanaged());
        assertNotSame("Expected connection be proxied", connection, connectionProxy);


        // simulate handle release due to a event listener, which won't hav the proxy
        connectionTrackingCoordinator.handleReleased(key1, createConnectionInfo(), ConnectionReturnAction.RETURN_HANDLE);

        // proxy should be disconnected
        ConnectionTrackingCoordinator.ConnectionInvocationHandler invocationHandler = (ConnectionTrackingCoordinator.ConnectionInvocationHandler) Proxy.getInvocationHandler(connectionProxy);
        assertTrue("Proxy should be disconnected", invocationHandler.isReleased());

        // use connection which will cause it to get a new handle if it is not closed
        assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
        assertTrue("Proxy should be connected", invocationHandler.isReleased());
        assertSame("Expected connection.getUnmanaged() to be original connection", connection, connection.getUnmanaged());

        // exit outer component context
        connectionTrackingCoordinator.exit(oldConnectorInstanceContext1);

        // proxy should be disconnected
        assertTrue("Proxy should be disconnected", invocationHandler.isReleased());

        // connection should not be in context
        connectionManagerMap = componentContext.getConnectionManagerMap();
        infos = connectionManagerMap.get(key1);
        assertNull("Expected no connection set for key1", infos);

        // enter again
        oldConnectorInstanceContext1 = connectionTrackingCoordinator.enter(componentContext);
        assertNull("Expected old component context to be null", oldConnectorInstanceContext1);

        // exit context
        connectionTrackingCoordinator.exit(oldConnectorInstanceContext1);

        // use connection which will cause it to get a new handle if it is not closed
        assertEquals("connection.getString()", "ConnectionString", connectionProxy.getString());
        assertTrue("Proxy should be connected", invocationHandler.isReleased());
        assertSame("Expected connection.getUnmanaged() to be original connection", connection, connection.getUnmanaged());
    }


    public Subject mapSubject(Subject sourceSubject) {
        return subject;
    }

    public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
    }

    public void returnConnection(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction) {
    }

    public void destroy() {
    }

    public void info(StringBuilder s) {
        s.append(getClass().getName()).append("\n");
    }

    private ConnectionInfo createConnectionInfo() {
        ConnectionInfo ci = new ConnectionInfo(mci);
        ci.setConnectionHandle(connection);
        mci.addConnectionHandle(ci);
        return ci;
    }


    public static interface Connection {
        String getString();
        Connection getUnmanaged();
    }

    public static class ConnectionImpl implements Connection {
        private final String string;

        public ConnectionImpl(String string) {
            this.string = string;
        }

        public String getString() {
            return string;
        }

        public Connection getUnmanaged() {
            return this;
        }
    }

    public static class MockManagedConnection implements ManagedConnection {
           public Object getConnection(Subject defaultSubject, ConnectionRequestInfo connectionRequestInfo) throws ResourceException {
               return null;
           }

           public void destroy() throws ResourceException {
           }

           public void cleanup() throws ResourceException {
           }

           public void associateConnection(Object object) throws ResourceException {
           }

           public void addConnectionEventListener(ConnectionEventListener connectionEventListener) {
           }

           public void removeConnectionEventListener(ConnectionEventListener connectionEventListener) {
           }

           public XAResource getXAResource() throws ResourceException {
               return null;
           }

           public LocalTransaction getLocalTransaction() throws ResourceException {
               return null;
           }

           public ManagedConnectionMetaData getMetaData() throws ResourceException {
               return null;
           }

           public void setLogWriter(PrintWriter printWriter) throws ResourceException {
           }

           public PrintWriter getLogWriter() throws ResourceException {
               return null;
           }

           public void dissociateConnections() throws ResourceException {
           }
       }
}
