package com.github.wxiaoqi.security.common.config.rabbit;

import cn.hutool.core.util.StrUtil;
import com.github.wxiaoqi.security.common.config.rabbit.BindDTO;
import com.github.wxiaoqi.security.common.config.rabbit.RabbitConstant;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * rabbitmq配置类
 * 包含： 不知道什么orderWater队列
 * @author zhoujw
 * @date 2019/7/15
 */
public abstract class RabbitCommonConfig {
    @Autowired
    ConfigurableApplicationContext applicationContext;

    public static List<BindDTO> myQueue;

    public <T> T registerBean(String name, Class<T> clazz, Object... args) {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
        if (args.length > 0) {
            for (Object arg : args) {
                beanDefinitionBuilder.addConstructorArgValue(arg);
            }
        }
        BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();

        BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) applicationContext.getBeanFactory();
        beanFactory.registerBeanDefinition(name, beanDefinition);
        return applicationContext.getBean(name, clazz);
    }

    @Bean
    public void registerQueueWithBind() {
        if(null != RabbitConstant.exchangeTopicSet) {
            RabbitConstant.exchangeTopicSet.forEach(k -> {
                registerBean(StrUtil.toCamelCase(k), TopicExchange.class, k, true, false);
            });
        }

        if(null != myQueue) {
            myQueue.forEach(en -> {
                //避免一个队列绑定多个exchange+key 时 再次创建queueBean
                try {
                    Queue queue = applicationContext.getBean(StrUtil.toCamelCase(en.getQueue()), Queue.class);
                }catch (Exception e) {
                    registerBean(StrUtil.toCamelCase(en.getQueue()), Queue.class, en.getQueue(), Boolean.TRUE);
                }
                String bindName = StrUtil.toCamelCase(en.getQueue())+ "Binding"+ en.getExchange()+ "_"+ en.getKey();
                registerBean(bindName, Binding.class, en.getQueue(), Binding.DestinationType.QUEUE, en.getExchange(), en.getKey(), Collections.EMPTY_MAP);
            });
        }
    }

}

