package com.yxcheng.tax.mq.rabbit.config;

import com.rabbitmq.client.Channel;


import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;


@Component
@Configuration
public class AmqpConfig {
    private static Logger logger = LoggerFactory.getLogger(AmqpConfig.class);

    @Value("${spring.rabbitmq.host}")
    String host;
    @Value("${spring.rabbitmq.port}")
    int port;
    @Value("${spring.rabbitmq.username}")
    String username;
    @Value("${spring.rabbitmq.password}")
    String password;
    @Value("${spring.rabbitmq.virtual-host}")
    String virtualHost;
    @Value("${spring.rabbitmq.publisher-confirms}")
    private boolean publisherConfirms;

    @Value("${spring.rabbitmq.exchageName}")
    @Getter String exchangeName;
    @Value("${spring.rabbitmq.queue.pushToken}")
    @Getter String pushTokenQueueName;
    @Value("${spring.rabbitmq.routeKey.pushToken}")
    @Getter String pushTokenRoutingKey ;

    @Value("${spring.rabbitmq.queue.pushTokenNew}")
    @Getter String pushTokenNewQueueName;
    @Value("${spring.rabbitmq.routeKey.pushTokenNew}")
    @Getter String pushTokenNewRoutingKey ;
    @Value("${spring.rabbitmq.isRun}")
    boolean isRun;


    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setAddresses(host + ":" + port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost(virtualHost);
        /** 如果要进行消息回调，则这里必须要设置为true */
        connectionFactory.setPublisherConfirms(publisherConfirms);
        return connectionFactory;
    }

    /** 因为要设置回调类，所以应是prototype类型，如果是singleton类型，则回调类为最后一次设置 */
    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        //发布确认
        template.setConfirmCallback((CorrelationData correlationData, boolean ack, String cause) ->{
              //  logger.info("correlationData:{},ack:{},cause",correlationData.getId(),ack,cause);
                if (!ack){
                    logger.debug("correlationData:{} 发送到queue失败",correlationData);
                }
            }
        );
        return template;
    }


    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        if (!isRun) {
            //是否自动启动
            factory.setAutoStartup(false);
        }
        return factory;
    }

    @Bean
    TopicExchange exchange() {
        return new TopicExchange(exchangeName);
    }

    @Bean
    public Queue pushTokenQueue() {
        return new Queue(pushTokenQueueName, true);
    }


    @Bean
    public Binding binding() {
        return BindingBuilder.bind(pushTokenQueue()).to(exchange()).with(pushTokenRoutingKey);
    }


    @Bean
    public Queue pushTokenNewQueue() {
        return new Queue(pushTokenNewQueueName, true);
    }


    @Bean
    public Binding bindingPushTokenNew() {
        return BindingBuilder.bind(pushTokenNewQueue()).to(exchange()).with(pushTokenNewRoutingKey);
    }


}

