package com.liquidnet.common.mq.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

/**
 * Created by guo_x on 2016/11/19.
 */
@Configuration
@EnableRabbit
@Component
public class RabbitMQConfigration {
    Logger logger = LoggerFactory.getLogger(RabbitMQConfigration.class);

    @Autowired
    private MQProperties mqProperties;

    @Autowired
    private ConnectionFactory rabbitConnectionFactory;

    @Bean("rabbitAdmin")
    @ConditionalOnSingleCandidate(ConnectionFactory.class)
    public RabbitAdmin rabbitAdmin() {
        return new RabbitAdmin(rabbitConnectionFactory);
    }

    @Bean("rabbitTemplate")
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)//必须是prototype类型
    public RabbitTemplate rabbitTemplate() {
      logger.info("########################初始化rabitTemplate################################");
      RabbitTemplate r = new RabbitTemplate(rabbitConnectionFactory);
      r.setExchange(mqProperties.getDefaultTopicExchange());
//    r.setMessageConverter(new Jackson2JsonMessageConverter());
      return r;
    }

    @Bean("rabbitListenerContainerFactory")
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
        logger.info("########################初始化rabbitListenerContainerFactory################################");
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(rabbitConnectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        return factory;
    }

    /**
     * 针对消费者配置
     * FanoutExchange: 将消息分发到所有的绑定队列，无routingkey的概念
     * HeadersExchange ：通过添加属性key-value匹配
     * DirectExchange:按照routingkey分发到指定队列
     * TopicExchange:多关键字匹配
     */
    @ConditionalOnProperty(name = "mq.config.default-direct-exchange")
    public DirectExchange defaultDirectExchange() {
        logger.info("初始化defaultDirectExchange:{}", mqProperties.getDefaultDirectExchange());
        return new DirectExchange(mqProperties.getDefaultDirectExchange(), true, false);
    }

    @ConditionalOnProperty(name = "mq.config.default-topic-exchange")
    public TopicExchange defaltTopicExchange() {
        logger.info("初始化defaultTopicExchange:{}", mqProperties.getDefaultTopicExchange());
        return new TopicExchange(mqProperties.getDefaultTopicExchange(), true, false);
    }


    @Bean
    @ConditionalOnProperty(name = "mq.config.data-send-queue")
    public Queue dataSendQueue(){
        logger.info("创建打点数据监听队列：{}",mqProperties.getDataSendQueue());
        return new Queue(mqProperties.getDataSendQueue());
    }

    @Bean
    @ConditionalOnBean(name = "dataSendQueue")
    public Binding bindDataSend(){
        logger.info("绑定打点数据队列，exchange:{},routingKey:{},queueName:{}", mqProperties.getDefaultTopicExchange(), mqProperties.getDataSendRoutingKey(), mqProperties.getDataSendQueue());
        return BindingBuilder.bind(dataSendQueue()).to(defaltTopicExchange()).with(mqProperties.getDataSendRoutingKey());
    }

    @Bean
    @ConditionalOnProperty(name = "mq.config.overdue-signinfo-queue")
    public Queue overdueSigninfoQueue(){
        logger.info("创建签约信息监听队列：{}",mqProperties.getOverdueSigninfoQueue());
        return new Queue(mqProperties.getOverdueSigninfoQueue());
    }

    @Bean
    @ConditionalOnBean(name = "overdueSigninfoQueue")
    public Binding bindOverdueSigninfo(){
        logger.info("绑定签约信息队列，exchange:{},routingKey:{},queueName:{}", mqProperties.getDefaultTopicExchange(), mqProperties.getOverdueSigninfoRoutingKey(), mqProperties.getOverdueSigninfoQueue());
        return BindingBuilder.bind(overdueSigninfoQueue()).to(defaltTopicExchange()).with(mqProperties.getOverdueSigninfoRoutingKey());
    }



    @Bean
    @ConditionalOnProperty(name = "mq.config.overdue-repayment-queue")
    public Queue overdueRepaymentQueue(){
        logger.info("创建还款推送监听队列：{}",mqProperties.getOverdueRepaymentQueue());
        return new Queue(mqProperties.getOverdueRepaymentQueue());
    }

    @Bean
    @ConditionalOnBean(name = "overdueRepaymentQueue")
    public Binding bindOverdueRepayment(){
        logger.info("绑定还款推送监听队列，exchange:{},routingKey:{},queueName:{}", mqProperties.getDefaultTopicExchange(), mqProperties.getOverdueRepaymentRoutingKey(), mqProperties.getOverdueRepaymentQueue());
        return BindingBuilder.bind(overdueRepaymentQueue()).to(defaltTopicExchange()).with(mqProperties.getOverdueRepaymentRoutingKey());
    }



    @Bean
    @ConditionalOnProperty(name = "mq.config.overdue-penaltymoney-queue")
    public Queue overduePenaltymoneyQueue(){
        logger.info("创建逾期违约金额推送监听队列：{}",mqProperties.getOverduePenaltymoneyQueue());
        return new Queue(mqProperties.getOverduePenaltymoneyQueue());
    }

    @Bean
    @ConditionalOnBean(name = "overduePenaltymoneyQueue")
    public Binding bindOverduePenaltymoney(){
        logger.info("绑定逾期违约金额推送监听队列，exchange:{},routingKey:{},queueName:{}", mqProperties.getDefaultTopicExchange(), mqProperties.getOverduePenaltymoneyRoutingKey(), mqProperties.getOverduePenaltymoneyQueue());
        return BindingBuilder.bind(overduePenaltymoneyQueue()).to(defaltTopicExchange()).with(mqProperties.getOverduePenaltymoneyRoutingKey());
    }

    @Bean
    @ConditionalOnProperty(name = "mq.config.loan-repaymentplan-queue")
    public Queue loanRepaymentplanQueue(){
        logger.info("创建三方数据推送监听队列：{}",mqProperties.getLoanRepaymentplanQueue());
        return new Queue(mqProperties.getLoanRepaymentplanQueue());
    }


    @Bean
    @ConditionalOnBean(name = "loanRepaymentplanQueue")
    public Binding bindLoanRepaymentplanQueue(){
        logger.info("三方数据推送监听队列, exchange:{},routingKey:{},queueName:{}",mqProperties.getDefaultTopicExchange(),mqProperties.getLoanRepaymentplanRoutingKey(),mqProperties.getLoanRepaymentplanQueue());
        return BindingBuilder.bind(loanRepaymentplanQueue()).to(defaltTopicExchange()).with(mqProperties.getLoanRepaymentplanRoutingKey());
    }


    @Bean
    @ConditionalOnProperty(name = "mq.config.loan-pushdata-queue")
    public Queue loanPushDataQueue(){
        logger.info("创建接收冲账成功数据推送监听队列：{}",mqProperties.getLoanPushdataQueue());
        return new Queue(mqProperties.getLoanPushdataQueue());
    }


    @Bean
    @ConditionalOnBean(name = "loanPushDataQueue")
    public Binding bindLoanPushDataQueue(){
        logger.info("三方数据推送监听队列, exchange:{},routingKey:{},queueName:{}",mqProperties.getDefaultTopicExchange(),mqProperties.getLoanPushdataRoutingKey(),mqProperties.getLoanPushdataQueue());
        return BindingBuilder.bind(loanPushDataQueue()).to(defaltTopicExchange()).with(mqProperties.getLoanPushdataRoutingKey());
    }


}
