package com.quantgroup.asset.distribution.config.rabbitmq;

import cn.quantgroup.tech.brave.service.ITechRabbitBuilder;
import com.google.common.collect.ImmutableMap;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.annotation.Resource;

/**
 * Created by Miraculous on 16/5/18.
 */
@Configuration
@EnableRabbit
public class RabbitMqConfig {

    @Value("${rabbitmq.connection.host}")
    private String host;
    @Value("${rabbitmq.connection.port}")
    private Integer port;
    @Value("${rabbitmq.connection.user}")
    private String user;
    @Value("${rabbitmq.connection.password}")
    private String password;
    @Value("${rabbitmq.connection.virtual-host}")
    private String virtualHost;
    @Value("${rabbitmq.connection.funding.exchange}")
    private String fundingStateChangeExchange;
    @Value("${rabbitmq.connection.funding.statechange.queue}")
    private String fundingStateChangeQueue;

    @Resource
    private ITechRabbitBuilder techRabbitBuilder;

    @Bean(name = "assetDistributionConnectionFactory")
    @Primary
    public CachingConnectionFactory cachingConnectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host, port);
        connectionFactory.setChannelCacheSize(1024);
        connectionFactory.setCacheMode(CachingConnectionFactory.CacheMode.CONNECTION);
        connectionFactory.setChannelCacheSize(180 * 1000);
        connectionFactory.setConnectionCacheSize(1024);
        connectionFactory.setUsername(user);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost(virtualHost);
        connectionFactory.setPublisherReturns(false);
        connectionFactory.setPublisherConfirms(false);
        return connectionFactory;
    }

    @Bean(name="assetDistributionRabbitAdmin")
    @Primary
    public RabbitAdmin rabbitAdmin(@Qualifier("assetDistributionConnectionFactory")CachingConnectionFactory assetDistributionConnectionFactory) {
        return new RabbitAdmin(assetDistributionConnectionFactory);
    }

    /**
     * 声明一个交换机
     * @param assetDistributionRabbitAdmin
     * @return
     */
    @Bean(name = "fundingStateExchange")
    @Primary
    public FanoutExchange fundingStateExchange(@Qualifier("assetDistributionRabbitAdmin")RabbitAdmin assetDistributionRabbitAdmin) {
        FanoutExchange fanoutExchange = new FanoutExchange(fundingStateChangeExchange);
        assetDistributionRabbitAdmin.declareExchange(fanoutExchange);
        return fanoutExchange;
    }

    /**
     * 声明一个队列
     * @param assetDistributionRabbitAdmin
     * @return
     */
    @Bean(name = "fundingStateChangeQueue")
    @Primary
    public Queue loanOrderQueue(@Qualifier("assetDistributionRabbitAdmin")RabbitAdmin assetDistributionRabbitAdmin){
        //消息过期时间
        ImmutableMap<String,Object> map = ImmutableMap.of("x-message-ttl", 300000);//5分钟
        Queue queue = new Queue(fundingStateChangeQueue, true,false,false,map);
        assetDistributionRabbitAdmin.declareQueue(queue);
        return queue;
    }

    /**
     * 队列绑定到交换机上
     * @param assetDistributionRabbitAdmin
     * @param fundingStateChangeQueue
     * @param fundingStateExchange
     * @return
     */
    @Bean(name = "fundingStateQueueBinding")
    @Primary
    public Binding bindingLoanOrderQueue(@Qualifier("assetDistributionRabbitAdmin")AmqpAdmin assetDistributionRabbitAdmin,
                                         @Qualifier("fundingStateChangeQueue")Queue fundingStateChangeQueue,
                                         @Qualifier("fundingStateExchange")FanoutExchange fundingStateExchange) {
        Binding binding = BindingBuilder.bind(fundingStateChangeQueue).to(fundingStateExchange);
        assetDistributionRabbitAdmin.declareBinding(binding);
        return binding;
    }

    
    
}
