package com.cf.imes.framework.mq.rabbitmq.config;

import com.cf.imes.framework.common.util.encrypt.AesUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.amqp.CachingConnectionFactoryConfigurer;
import org.springframework.boot.autoconfigure.amqp.ConnectionFactoryCustomizer;
import org.springframework.boot.autoconfigure.amqp.RabbitConnectionFactoryBeanConfigurer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;

/**
 * @author Gqr
 * @since 2025/3/13 13:53
 */
@AutoConfiguration
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "true")
public class ChenfengRabbitMQEncryptAutoConfiguration {
    @Value("${chenfeng.encrypt.publicKey:}")
    private String publicKey;

    /**
     * 参考 org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration 的 rabbitConnectionFactory 方法
     */
    @Bean
    @Primary
    CachingConnectionFactory rabbitConnectionFactory(
            RabbitConnectionFactoryBeanConfigurer rabbitConnectionFactoryBeanConfigurer,
            CachingConnectionFactoryConfigurer rabbitCachingConnectionFactoryConfigurer,
            ObjectProvider<ConnectionFactoryCustomizer> connectionFactoryCustomizers) throws Exception {

        RabbitConnectionFactoryBean connectionFactoryBean = new RabbitConnectionFactoryBean();
        rabbitConnectionFactoryBeanConfigurer.configure(connectionFactoryBean);
        connectionFactoryBean.afterPropertiesSet();
        com.rabbitmq.client.ConnectionFactory connectionFactory = connectionFactoryBean.getObject();

        if (StringUtils.isNotEmpty(publicKey)) {
            connectionFactory.setUsername(AesUtils.decrypt(connectionFactory.getUsername(), publicKey));
            connectionFactory.setPassword(AesUtils.decrypt(connectionFactory.getPassword(), publicKey));
        }
        connectionFactoryCustomizers.orderedStream()
                .forEach((customizer) -> customizer.customize(connectionFactory));

        CachingConnectionFactory factory = new CachingConnectionFactory(connectionFactory);
        rabbitCachingConnectionFactoryConfigurer.configure(factory);

        return factory;
    }
}
