/**
 * 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.activemq.camel.component;

import static org.junit.Assert.assertNotNull;

import java.util.concurrent.TimeUnit;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.pool.PooledConnectionFactory;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ComplexRequestReplyTest {

    private static final Logger LOG = LoggerFactory.getLogger(ComplexRequestReplyTest.class);

    private BrokerService brokerA = null;
    private BrokerService brokerB = null;
    private CamelContext senderContext = null;
    private CamelContext brokerAContext = null;
    private CamelContext brokerBContext = null;

    private final String fromEndpoint = "direct:test";
    private final String toEndpoint = "activemq:queue:send";
    private final String brokerEndpoint = "activemq:send";

    private String brokerAUri;
    private String brokerBUri;

    private String connectionUri;

    @Before
    public void setUp() throws Exception {

        createBrokerA();
        brokerAUri = brokerA.getTransportConnectors().get(0).getPublishableConnectString();
        createBrokerB();
        brokerBUri = brokerB.getTransportConnectors().get(0).getPublishableConnectString();

        connectionUri = "failover:(" + brokerAUri + "," + brokerBUri + ")?randomize=false";
        senderContext = createSenderContext();
    }

    @After
    public void tearDown() throws Exception {
        try {
            shutdownBrokerA();
        } catch (Exception ex) {}

        try {
            shutdownBrokerB();
        } catch (Exception e) {}
    }

    @Test
    public void testSendThenFailoverThenSend() throws Exception {

        ProducerTemplate requester = senderContext.createProducerTemplate();
        LOG.info("*** Sending Request 1");
        String response = (String) requester.requestBody(fromEndpoint, "This is a request");
        assertNotNull(response != null);
        LOG.info("Got response: " + response);

        /**
         * You actually don't need to restart the broker, just wait long enough and the next
         * next send will take out a closed connection and reconnect, and if you happen to hit
         * the broker you weren't on last time, then you will see the failure.
         */

        TimeUnit.SECONDS.sleep(20);

        /**
         * I restart the broker after the wait that exceeds the idle timeout value of the
         * PooledConnectionFactory to show that it doesn't matter now as the older connection
         * has already been closed.
         */
        LOG.info("Restarting Broker A now.");
        shutdownBrokerA();
        createBrokerA();

        LOG.info("*** Sending Request 2");
        response = (String) requester.requestBody(fromEndpoint, "This is a request");
        assertNotNull(response != null);
        LOG.info("Got response: " + response);
    }

    private CamelContext createSenderContext() throws Exception {

        ActiveMQConnectionFactory amqFactory = new ActiveMQConnectionFactory(connectionUri);
        amqFactory.setWatchTopicAdvisories(false);

        PooledConnectionFactory pooled = new PooledConnectionFactory(amqFactory);
        pooled.setMaxConnections(1);
        pooled.setMaximumActiveSessionPerConnection(500);
        // If this is not zero the connection could get closed and the request
        // reply can fail.
        pooled.setIdleTimeout(0);

        CamelContext camelContext = new DefaultCamelContext();
        ActiveMQComponent amqComponent = new ActiveMQComponent();
        amqComponent.setConnectionFactory(pooled);
        camelContext.addComponent("activemq", amqComponent);
        camelContext.addRoutes(new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from(fromEndpoint).inOut(toEndpoint);
            }
        });
        camelContext.start();

        return camelContext;
    }

    private void createBrokerA() throws Exception {
        brokerA = createBroker("brokerA");
        brokerAContext = createBrokerCamelContext("brokerA");
        brokerA.start();
        brokerA.waitUntilStarted();
    }

    private void shutdownBrokerA() throws Exception {
        try {
            brokerAContext.stop();
        } catch (Exception e) {
            brokerA.stop();
            brokerA.waitUntilStopped();
            brokerA = null;
        }
    }

    private void createBrokerB() throws Exception {
        brokerB = createBroker("brokerB");
        brokerBContext = createBrokerCamelContext("brokerB");
        brokerB.start();
        brokerB.waitUntilStarted();
    }

    private void shutdownBrokerB() throws Exception {
        try {
            brokerBContext.stop();
        } finally {
            brokerB.stop();
            brokerB.waitUntilStopped();
            brokerB = null;
        }
    }

    private BrokerService createBroker(String name) throws Exception {
        BrokerService service = new BrokerService();
        service.setPersistent(false);
        service.setUseJmx(false);
        service.setBrokerName(name);
        service.addConnector("tcp://localhost:0");

        return service;
    }

    private CamelContext createBrokerCamelContext(String brokerName) throws Exception {

        CamelContext camelContext = new DefaultCamelContext();
        camelContext.addComponent("activemq",
                ActiveMQComponent.activeMQComponent("vm://"+brokerName+"?create=false&waitForStart=10000"));
        camelContext.addRoutes(new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from(brokerEndpoint).setBody().simple("Returning ${body}").log("***Reply sent to ${header.JMSReplyTo} CoorId = ${header.JMSCorrelationID}");
            }
        });
        camelContext.start();
        return camelContext;
    }
}
