/*
 * 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.systests.jms_1_1.connection;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeThat;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;

import com.google.common.util.concurrent.SettableFuture;
import org.junit.Before;
import org.junit.Test;

import org.apache.qpid.server.model.Protocol;
import org.apache.qpid.systests.JmsTestBase;

public class SpontaneousConnectionCloseTest extends JmsTestBase
{
    private SettableFuture<JMSException> _connectionCloseFuture;

    @Before
    public void setUp() throws Exception
    {
        _connectionCloseFuture = SettableFuture.create();
    }

    @Test
    public void explictManagementConnectionClose() throws Exception
    {
        assumeThat(getBrokerAdmin().isManagementSupported(), is(true));

        Connection con = getConnection();
        try
        {
            con.setExceptionListener(_connectionCloseFuture::set);

            final UUID uuid = getConnectionUUID(con);

            closeConnectionUsingAmqpManagement(uuid);

            assertClientConnectionClosed(con);
        }
        finally
        {
            con.close();
        }
    }

    @Test
    public void brokerRestartConnectionClose() throws Exception
    {
        Connection con = getConnectionBuilder().setFailover(false).build();
        try
        {
            con.setExceptionListener(_connectionCloseFuture::set);

            getBrokerAdmin().restart();

            assertClientConnectionClosed(con);
        }
        finally
        {
            con.close();
        }
    }

    private void assertClientConnectionClosed(final Connection con) throws Exception
    {
        _connectionCloseFuture.get(getReceiveTimeout(), TimeUnit.MILLISECONDS);
        try
        {
            con.createSession(false, Session.AUTO_ACKNOWLEDGE);
            fail("Connection close ought to invalidate further use");
        }
        catch (JMSException e)
        {
            // PASS
        }
    }

    private UUID getConnectionUUID(final Connection connection) throws Exception
    {
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        MapMessage message = session.createMapMessage();

        message.setStringProperty("type", "org.apache.qpid.VirtualHost");
        message.setStringProperty("operation", "getConnectionMetaData");
        message.setStringProperty("index", "object-path");
        message.setStringProperty("key", "");

        MapMessage response = (MapMessage) sendManagementRequestAndGetResponse(session, message, 200);

        return UUID.fromString(String.valueOf(response.getObject("connectionId")));
    }

    private void closeConnectionUsingAmqpManagement(final UUID targetConnectionId) throws Exception
    {
        Connection connection = getConnection();
        try
        {
            connection.start();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            MapMessage message = session.createMapMessage();
            message.setStringProperty("operation", "DELETE");
            message.setStringProperty("type", "org.apache.qpid.Connection");
            message.setStringProperty("identity", String.valueOf(targetConnectionId));

            sendManagementRequestAndGetResponse(session, message, 204);
        }
        finally
        {
            connection.close();
        }
    }

    private Message sendManagementRequestAndGetResponse(final Session session,
                                                        final MapMessage request,
                                                        final int expectedResponseCode) throws Exception
    {
        final Queue queue;
        final Queue replyConsumer;
        Queue replyAddress;

        if (getProtocol() == Protocol.AMQP_1_0)
        {
            queue = session.createQueue("$management");
            replyAddress = session.createTemporaryQueue();
            replyConsumer = replyAddress;
        }
        else
        {
            queue = session.createQueue("ADDR:$management");
            replyAddress = session.createQueue("ADDR:!response");
            replyConsumer = session.createQueue(
                    "ADDR:$management ; {assert : never, node: { type: queue }, link:{name: \"!response\"}}");
        }
        request.setJMSReplyTo(replyAddress);

        final MessageConsumer consumer = session.createConsumer(replyConsumer);
        final MessageProducer producer = session.createProducer(queue);

        producer.send(request);

        final Message responseMessage = consumer.receive(getReceiveTimeout());
        assertThat("The response code did not indicate success",
                   responseMessage.getIntProperty("statusCode"), is(equalTo(expectedResponseCode)));


        return responseMessage;
    }
}
