// Path: blog-code/src/main/java/pl/ciruk/blog/mq/MQConfiguration.java
// @Configuration
// @EnableJms
// public class MQConfiguration {
//     @Bean
//     public PlatformTransactionManager platformTransactionManager(ConnectionFactory connectionFactory) {
//         return new JmsTransactionManager(connectionFactory);
//     }
// 
//     @Bean
//     public DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory(PlatformTransactionManager transactionManager, ConnectionFactory connectionFactory) {
//         DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
//         factory.setConnectionFactory(connectionFactory);
//         factory.setTransactionManager(transactionManager);
//         factory.setConcurrency("5-10");
//         factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
//         factory.setSessionTransacted(true);
//         return factory;
//     }
// 
//     @Bean
//     public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
//         JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
//         return jmsTemplate;
//     }
// 
//     @Bean
//     public Consumer<String> messageConsumer() {
//         return System.out::println;
//     }
// }


import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import pl.ciruk.blog.mq.MQConfiguration;
import javax.inject.Inject;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

    @Test
    public void shouldPrintTwoReceivedMessagesAndRespondToOne() throws Exception {
        mockDestination
                .whenReceived(message -> message.equals(FIRST_MESSAGE))
                .thenSend(RESPONSE_QUEUE, message -> message + " acknowledged");
        mockDestination
                .whenReceived(message -> message.startsWith("A"))
                .thenConsume(message -> System.out.println("Received: " + message));

        send(FIRST_MESSAGE);
        send(SECOND_MESSAGE);

        System.out.println(jmsTemplate.receiveAndConvert(RESPONSE_QUEUE));
    }

    private void send(String firstMessage) {
        waitAMoment();
        jmsTemplate.convertAndSend("RequestQueue", firstMessage);
    }

    private void waitAMoment() {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            Thread.interrupted();
        }
    }

    @Configuration
// Path: blog-code/src/main/java/pl/ciruk/blog/mq/MQConfiguration.java
// @Configuration
// @EnableJms
// public class MQConfiguration {
//     @Bean
//     public PlatformTransactionManager platformTransactionManager(ConnectionFactory connectionFactory) {
//         return new JmsTransactionManager(connectionFactory);
//     }
// 
//     @Bean
//     public DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory(PlatformTransactionManager transactionManager, ConnectionFactory connectionFactory) {
//         DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
//         factory.setConnectionFactory(connectionFactory);
//         factory.setTransactionManager(transactionManager);
//         factory.setConcurrency("5-10");
//         factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
//         factory.setSessionTransacted(true);
//         return factory;
//     }
// 
//     @Bean
//     public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
//         JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
//         return jmsTemplate;
//     }
// 
//     @Bean
//     public Consumer<String> messageConsumer() {
//         return System.out::println;
//     }
// }


// Path: blog-code/src/test/java/pl/ciruk/blog/jms/MockDestinationIntegrationTest.java
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import pl.ciruk.blog.mq.MQConfiguration;
import javax.inject.Inject;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;


    @Test
    public void shouldPrintTwoReceivedMessagesAndRespondToOne() throws Exception {
        mockDestination
                .whenReceived(message -> message.equals(FIRST_MESSAGE))
                .thenSend(RESPONSE_QUEUE, message -> message + " acknowledged");
        mockDestination
                .whenReceived(message -> message.startsWith("A"))
                .thenConsume(message -> System.out.println("Received: " + message));

        send(FIRST_MESSAGE);
        send(SECOND_MESSAGE);

        System.out.println(jmsTemplate.receiveAndConvert(RESPONSE_QUEUE));
    }

    private void send(String firstMessage) {
        waitAMoment();
        jmsTemplate.convertAndSend("RequestQueue", firstMessage);
    }

    private void waitAMoment() {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            Thread.interrupted();
        }
    }

    @Configuration
    static class TestConfiguration extends MQConfiguration {