/*
 *
 * 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.qpid.test.unit.client.connection;

import java.util.Enumeration;

import javax.jms.Connection;
import javax.jms.ConnectionMetaData;
import javax.jms.QueueSession;
import javax.jms.TopicSession;

import org.apache.qpid.AMQConnectionFailureException;
import org.apache.qpid.AMQUnresolvedAddressException;
import org.apache.qpid.QpidException;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQConnectionURL;
import org.apache.qpid.client.AMQQueue;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.AMQTopic;
import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.jms.Session;
import org.apache.qpid.test.utils.QpidBrokerTestCase;

public class ConnectionTest extends QpidBrokerTestCase
{

    private String _broker_NotRunning = "tcp://localhost:" + findFreePort();

    private String _broker_BadDNS = "tcp://unknownhost.unknowndomain.invalid"; // RFC-2606 guarantees that .invalid address will never resolve

    public void testSimpleConnection() throws Exception
    {
        AMQConnection conn = null;
        try
        {
            conn = new AMQConnection(getBrokerDetailsFromDefaultConnectionUrl().toString(), "guest", "guest", "fred", "test");
        }
        catch (Exception e)
        {
            fail("Connection to " + getBrokerDetailsFromDefaultConnectionUrl() + " should succeed. Reason: " + e);
        }
        finally
        {
            if(conn != null)
            {
                conn.close();
            }
        }
    }

    public void testDefaultExchanges() throws Exception
    {
        AMQConnection conn = null;
        try
        {
            String broker = getBrokerDetailsFromDefaultConnectionUrl();
            //broker.setProperty(BrokerDetails.OPTIONS_RETRY, "1");
            ConnectionURL url = new AMQConnectionURL("amqp://guest:guest@clientid/test?brokerlist='"
                                     + broker
                                     + "'&defaultQueueExchange='test.direct'"
                                     + "&defaultTopicExchange='test.topic'"
                                     + "&temporaryQueueExchange='tmp.direct'"
                                     + "&temporaryTopicExchange='tmp.topic'");

            conn = new AMQConnection(url);


            AMQSession sess = (AMQSession) conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

            sess.declareExchange("test.direct", ExchangeDefaults.DIRECT_EXCHANGE_CLASS, false);

            sess.declareExchange("tmp.direct", ExchangeDefaults.DIRECT_EXCHANGE_CLASS, false);

            sess.declareExchange("tmp.topic", ExchangeDefaults.TOPIC_EXCHANGE_CLASS, false);

            sess.declareExchange("test.topic", ExchangeDefaults.TOPIC_EXCHANGE_CLASS, false);

            QueueSession queueSession = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

            AMQQueue queue = (AMQQueue) queueSession.createQueue("MyQueue");

            assertEquals(queue.getExchangeName(), "test.direct");

            AMQQueue tempQueue = (AMQQueue) queueSession.createTemporaryQueue();

            assertEquals(tempQueue.getExchangeName(), "tmp.direct");

            queueSession.close();

            TopicSession topicSession = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);

            AMQTopic topic = (AMQTopic) topicSession.createTopic("silly.topic");

            assertEquals(topic.getExchangeName(), "test.topic");

            AMQTopic tempTopic = (AMQTopic) topicSession.createTemporaryTopic();

            assertEquals(tempTopic.getExchangeName(), "tmp.topic");

            topicSession.close();

        }
        catch (Exception e)
        {
            fail("Connection to " + getBrokerDetailsFromDefaultConnectionUrl()
                 + " should succeed. Reason: " + e);
        }
        finally
        {
            conn.close();
        }
    }

    public void testPasswordFailureConnection() throws Exception
    {
        AMQConnection conn = null;
        try
        {
            String broker = getBrokerDetailsFromDefaultConnectionUrl();
            conn = new AMQConnection("amqp://guest:rubbishpassword@clientid/test?brokerlist='" + broker + "'");
            fail("Connection should not be established password is wrong.");
        }
        catch (AMQConnectionFailureException amqe)
        {
            assertNotNull("No cause set:" + amqe.getMessage(), amqe.getCause());
            assertTrue("Exception was wrong type", amqe.getCause() instanceof QpidException);
        }
        finally
        {
            if (conn != null)
            {
                conn.close();
            }
        }
    }

    public void testConnectionFailure() throws Exception
    {
        AMQConnection conn = null;
        try
        {
            conn = new AMQConnection("amqp://guest:guest@clientid/testpath?brokerlist='" + _broker_NotRunning + "?retries='0''");
            fail("Connection should not be established");
        }
        catch (QpidException amqe)
        {
            if (!(amqe instanceof AMQConnectionFailureException))
            {
                fail("Correct exception not thrown. Expected 'AMQConnectionException' got: " + amqe);
            }
        }
        finally
        {
            if (conn != null)
            {
                conn.close();
            }
        }

    }

    public void testUnresolvedHostFailure() throws Exception
    {
        AMQConnection conn = null;
        try
        {
            conn = new AMQConnection("amqp://guest:guest@clientid/testpath?brokerlist='" + _broker_BadDNS + "?retries='0''");
            fail("Connection should not be established");
        }
        catch (QpidException amqe)
        {
            if (!(amqe instanceof AMQUnresolvedAddressException))
            {
                fail("Correct exception not thrown. Expected 'AMQUnresolvedAddressException' got: " + amqe);
            }
        }
        finally
        {
            if (conn != null)
            {
                conn.close();
            }
        }

    }

    public void testUnresolvedVirtualHostFailure() throws Exception
    {
        AMQConnection conn = null;
        try
        {
            String broker = getBrokerDetailsFromDefaultConnectionUrl();
            conn = new AMQConnection("amqp://guest:guest@clientid/rubbishhost?brokerlist='" + broker + "'");
            fail("Connection should not be established");
        }
        catch (QpidException amqe)
        {
            if (!(amqe instanceof AMQConnectionFailureException))
            {
                fail("Correct exception not thrown. Expected 'AMQConnectionFailureException' got: " + amqe);
            }
        }
        finally
        {
            if (conn != null)
            {
                conn.close();
            }
        }
    }

    public void testClientIdCannotBeChanged() throws Exception
    {
        Connection connection = new AMQConnection(getBrokerDetailsFromDefaultConnectionUrl().toString(), "guest", "guest",
                                                  "fred", "test");
        try
        {
            connection.setClientID("someClientId");
            fail("No IllegalStateException thrown when resetting clientid");
        }
        catch (javax.jms.IllegalStateException e)
        {
            // PASS
        }
        finally
        {
            if (connection != null)
            {
                connection.close();
            }
        }
    }

    public void testClientIdIsPopulatedAutomatically() throws Exception
    {
        Connection connection = new AMQConnection(getBrokerDetailsFromDefaultConnectionUrl().toString(), "guest", "guest",
                                                  null, "test");
        try
        {
            assertNotNull(connection.getClientID());
        }
        finally
        {
            connection.close();
        }
        connection.close();
    }

    public void testUnsupportedSASLMechanism() throws Exception
    {
        String broker = getBrokerDetailsFromDefaultConnectionUrl() + String.format("?sasl_mechs='%s'", "MY_MECH");

        try
        {
            Connection connection = new AMQConnection(broker.toString(), "guest", "guest",
                    null, "test");
            connection.close();
            fail("The client should throw a ConnectionException stating the" +
            		" broker does not support the SASL mech specified by the client");
        }
        catch (Exception e)
        {
            assertTrue("Unexpected exception message : " + e.getMessage(),
                       e.getMessage().contains("Client and broker have no SASL mechanisms in common."));
            assertTrue("Unexpected exception message : " + e.getMessage(),
                    e.getMessage().contains("Client restricted itself to : MY_MECH"));

        }
    }

    /**
     * Tests that when the same user connects twice with same clientid, the second connection
     * fails if the clientid verification feature is enabled (which uses a dummy 0-10 Session
     * with the clientid as its name to detect the previous usage of the clientid by the user)
     */
    public void testClientIDVerificationForSameUser() throws Exception
    {
        setTestSystemProperty(ClientProperties.QPID_VERIFY_CLIENT_ID, "true");

        String broker = getBrokerDetailsFromDefaultConnectionUrl();
        Connection con = new AMQConnection(broker.toString(), "guest", "guest",
                                           "client_id", "test");
        try
        {

            Connection con2 = new AMQConnection(broker.toString(), "guest", "guest",
                                        "client_id", "test");

            fail("The client should throw a ConnectionException stating the" +
                    " client ID is not unique");
        }
        catch (Exception e)
        {
            assertTrue("Incorrect exception thrown: " + e.getMessage(),
                       e.getMessage().contains("ClientID must be unique"));
        }
        finally
        {
            if (con != null)
            {
                con.close();
            }
        }
    }

    /**
     * Tests that when different users connects with same clientid, the second connection
     * succeeds even though the clientid verification feature is enabled (which uses a dummy
     * 0-10 Session with the clientid as its name; these are only verified unique on a
     * per-principal basis)
     */
    public void testClientIDVerificationForDifferentUsers() throws Exception
    {
        setTestSystemProperty(ClientProperties.QPID_VERIFY_CLIENT_ID, "true");

        String broker = getBrokerDetailsFromDefaultConnectionUrl();
        Connection con = null;
        Connection con2 = null;
        try
        {
            con = new AMQConnection(broker.toString(), "guest", "guest",
                                        "client_id", "test");

            con2 = new AMQConnection(broker.toString(), "admin", "admin",
                                        "client_id", "test");
        }
        catch (Exception e)
        {
            fail("Unexpected exception thrown, client id was not unique but usernames were different! "
                 + e.getMessage());
        }
        finally
        {
            if (con != null)
            {
                con.close();
            }
            if (con2 != null)
            {
                con2.close();
            }
        }
    }

    public static junit.framework.Test suite()
    {
        return new junit.framework.TestSuite(ConnectionTest.class);
    }

    public void testExceptionWhenUserPassIsRequired() throws Exception
    {
        AMQConnection conn = null;
        try
        {
            String broker = getBrokerDetailsFromDefaultConnectionUrl();
            String url = "amqp:///test?brokerlist='" + broker + "?sasl_mechs='PLAIN%2520CRAM-MD5''";
            conn = new AMQConnection(url);
            conn.close();
            fail("Exception should be thrown as user name and password is required");
        }
        catch (Exception e)
        {
            if (!e.getMessage().contains("Username and Password is required for the selected mechanism"))
            {
                if (conn != null && !conn.isClosed())
                {
                    conn.close();
                }
                fail("Incorrect Exception thrown! The exception thrown is : " + e.getMessage());
            }
        }
    }

    public void testConnectionMetadata() throws Exception
    {
        Connection con = getConnection();
        ConnectionMetaData metaData = con.getMetaData();
        assertNotNull(metaData);

        assertNotNull("Provider version unexpectedly null", metaData.getProviderVersion());
        assertTrue("Provider version unexpectedly empty", metaData.getProviderVersion().length() > 0);

        assertTrue("Provider major version has unexpected value", metaData.getProviderMajorVersion() > -1);
        assertTrue("Provider minor version has unexpected value", metaData.getProviderMinorVersion() > -1);

        Enumeration names = metaData.getJMSXPropertyNames();
        assertNotNull("JMSXPropertyNames unexpectedly null", names);
        assertTrue("JMSXPropertyNames should have at least one name", names.hasMoreElements());
    }
}
