package net.yyc.common.rabbitmq.config;

import net.yyc.common.rabbitmq.core.JavaSerializationMessageConverter;
import net.yyc.common.rabbitmq.event.HnqzRemoteApplicationEvent;
import net.yyc.common.rabbitmq.exchange.DelayExchangeBuilder;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.support.ConsumerTagStrategy;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.cloud.bus.jackson.RemoteApplicationEventScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.UUID;

/**
 * 消息队列配置类
 *
 * @author zyf
 */
@Configuration
@RemoteApplicationEventScan(basePackageClasses = HnqzRemoteApplicationEvent.class)
public class RabbitMqConfig {

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        //设置忽略声明异常
        rabbitAdmin.setIgnoreDeclarationExceptions(true);
        return rabbitAdmin;
    }

    @Bean
    public MessageConverter messageConverter() {
        return new JavaSerializationMessageConverter();
    }

    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
            ConnectionFactory connectionFactory, MessageConverter messageConverter) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(messageConverter);
        return factory;
    }

    @Bean
    public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        //手动确认
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        //当前的消费者数量
        container.setConcurrentConsumers(1);
        //最大的消费者数量
        container.setMaxConcurrentConsumers(1);
        //是否重回队列
        container.setDefaultRequeueRejected(true);
        //消费端的标签策略
        container.setConsumerTagStrategy(new ConsumerTagStrategy() {
            @Override
            public String createConsumerTag(String queue) {
                return queue + "_" + UUID.randomUUID().toString();
            }
        });
        return container;
    }

    //@Bean
    //Queue orderQueue() {
    //    return QueueBuilder.durable("direct_mode_audited_task_archive_queue")
    //            .withArgument("x-dead-letter-exchange", DelayExchangeBuilder.DEFAULT_DLX_EXCHANGE)
    //            .withArgument("x-dead-letter-routing-key", DLX_ROUTING_KEY)
    //            .build();
    //}

    // 配置死信交换机
    //@Bean
    //DirectExchange dlxExchange() {
    //    return new DirectExchange(DLX_EXCHANGE);
    //}

     //配置死信队列
    //@Bean
    //Queue dlxQueue() {
    //    return new Queue("direct_dlx_audited_task_archive_queue", true);
    //}

    // 绑定死信队列到死信交换机
    //@Bean
    //Binding dlxBinding() {
    //    return BindingBuilder.bind(dlxQueue()).to(dlxExchange()).with(DLX_ROUTING_KEY);
    //}
    // 订单队列，消息过期后会转发到死信队列
    //public static final String ORDER_QUEUE = "order.queue";
    //public static final String ORDER_EXCHANGE = "order.exchange";
    //public static final String ORDER_ROUTING_KEY = "order.routing.key";

    // 死信队列和交换机
    public static final String DLX_QUEUE = "dlx.cso.queue";
    //public static final String DLX_EXCHANGE = "dlx.exchange";
    public static final String DLX_ROUTING_KEY = "dlx.routing.key";

    // 配置死信交换机
    @Bean
    DirectExchange dlxExchange() {
        return new DirectExchange(DelayExchangeBuilder.DEFAULT_DLX_EXCHANGE);
    }

    // 配置死信队列
    @Bean
    Queue dlxQueue() {
        return new Queue(DLX_QUEUE, true);
    }

    // 绑定死信队列到死信交换机
    @Bean
    Binding dlxBinding() {
        return BindingBuilder.bind(dlxQueue()).to(dlxExchange()).with(DLX_ROUTING_KEY);
    }
    //
    //// 配置订单队列，并设置死信交换机和路由键
    @Bean
    Queue orderQueue() {
        return QueueBuilder.durable("direct_mode_audited_task_archive_queue")
                .withArgument("x-dead-letter-exchange", DelayExchangeBuilder.DEFAULT_DLX_EXCHANGE)
                .withArgument("x-dead-letter-routing-key", DLX_ROUTING_KEY)
                .build();
    }
    //
    // 配置订单交换机
    @Bean
    DirectExchange orderExchange() {
        return new DirectExchange(DelayExchangeBuilder.DEFAULT_DELAY_EXCHANGE);
    }
    //
    //// 绑定订单队列到订单交换机
    @Bean
    Binding orderBinding() {
        return BindingBuilder.bind(orderQueue()).to(orderExchange()).with("direct_mode_audited_task_archive_queue");
    }
}
