package com.lutao.cloud.iot.mqtt.spring.client;

import com.lutao.cloud.iot.mqtt.core.client.IMqttClientConnectListener;
import com.lutao.cloud.iot.mqtt.core.client.MqttClient;
import com.lutao.cloud.iot.mqtt.core.client.MqttClientCreator;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;

/**
 * mqtt client 配置
 *

 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(
        prefix = MqttClientProperties.PREFIX,
        name = "enabled",
        havingValue = "true"
)
@EnableConfigurationProperties(MqttClientProperties.class)
public class MqttClientConfiguration {

    @Bean
    public MqttClientCreator mqttClientCreator(MqttClientProperties properties,
                                               ObjectProvider<IMqttClientConnectListener> clientConnectListenerObjectProvider,
                                               ObjectProvider<MqttClientCustomizer> customizers) {
        MqttClientCreator clientCreator = MqttClient.create()
                .name(properties.getName())
                .ip(properties.getIp())
                .port(properties.getPort())
                .username(properties.getUserName())
                .password(properties.getPassword())
                .clientId(properties.getClientId())
                .readBufferSize(properties.getReadBufferSize())
                .maxBytesInMessage(properties.getMaxBytesInMessage())
                .maxClientIdLength(properties.getMaxClientIdLength())
                .keepAliveSecs(properties.getKeepAliveSecs())
                .reconnect(properties.isReconnect())
                .version(properties.getVersion())
                .cleanSession(properties.isCleanSession())
                .bufferAllocator(properties.getBufferAllocator());
        Integer timeout = properties.getTimeout();
        if (timeout != null && timeout > 0) {
            clientCreator.timeout(timeout);
        }
        Long reInterval1 = properties.getReInterval();
        if (reInterval1 != null && reInterval1 > 0) {
            clientCreator.reInterval(reInterval1);
        }
        // 构造遗嘱消息
        MqttClientProperties.WillMessage willMessage = properties.getWillMessage();
        if (willMessage != null && StringUtils.hasText(willMessage.getTopic())) {
            clientCreator.willMessage(builder -> {
                builder.topic(willMessage.getTopic())
                        .qos(willMessage.getQos())
                        .retain(willMessage.isRetain());
                if (StringUtils.hasText(willMessage.getMessage())) {
                    builder.message(willMessage.getMessage().getBytes(StandardCharsets.UTF_8));
                }
            });
        }
        // 配置客户端链接监听器
        clientConnectListenerObjectProvider.ifAvailable(clientCreator::connectListener);
        // 自定义处理
        customizers.ifAvailable((customizer) -> customizer.customize(clientCreator));
        return clientCreator;
    }

    @Bean
    public MqttClientTemplate mqttClientTemplate(MqttClientCreator mqttClientCreator) {
        return new MqttClientTemplate(mqttClientCreator);
    }

    @Bean
    public MqttClientSubscribeDetector mqttClientSubscribeDetector(MqttClientTemplate clientTemplate) {
        return new MqttClientSubscribeDetector(clientTemplate);
    }

}
