package com.lingniu.ingest.inbound.mqtt.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lingniu.ingest.core.dispatcher.Dispatcher;
import com.lingniu.ingest.identity.VehicleIdentityResolver;
import com.lingniu.ingest.inbound.mqtt.client.MqttEndpointManager;
import com.lingniu.ingest.inbound.mqtt.handler.MqttRealtimeHandler;
import com.lingniu.ingest.inbound.mqtt.mapper.YutongEventMapper;
import com.lingniu.ingest.inbound.mqtt.parser.MqttPayloadParser;
import com.lingniu.ingest.inbound.mqtt.profile.MqttProfile;
import com.lingniu.ingest.inbound.mqtt.profile.MqttProfileRegistry;
import com.lingniu.ingest.inbound.mqtt.profile.YutongMqttProfile;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
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.Conditional;
import org.springframework.context.annotation.Lazy;

import java.util.List;

@AutoConfiguration
@EnableConfigurationProperties(MqttInboundProperties.class)
@Conditional(MqttInboundEnabledCondition.class)
public class MqttInboundAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public ObjectMapper mqttObjectMapper() {
        return new ObjectMapper();
    }

    @Bean
    @ConditionalOnMissingBean
    public MqttPayloadParser mqttPayloadParser(ObjectMapper objectMapper) {
        return new MqttPayloadParser(objectMapper);
    }

    @Bean
    @ConditionalOnMissingBean
    public YutongEventMapper yutongEventMapper(VehicleIdentityResolver identityResolver) {
        return new YutongEventMapper(identityResolver);
    }

    @Bean
    @ConditionalOnMissingBean
    public YutongMqttProfile yutongMqttProfile(MqttPayloadParser parser, YutongEventMapper mapper) {
        return new YutongMqttProfile(parser, mapper);
    }

    @Bean
    @ConditionalOnMissingBean
    public MqttProfileRegistry mqttProfileRegistry(List<MqttProfile> profiles) {
        return new MqttProfileRegistry(profiles);
    }

    @Bean
    @ConditionalOnMissingBean
    public MqttRealtimeHandler mqttRealtimeHandler(MqttProfileRegistry profileRegistry) {
        return new MqttRealtimeHandler(profileRegistry);
    }

    @Bean(destroyMethod = "close")
    @Lazy(false)
    @ConditionalOnMissingBean
    public MqttEndpointManager mqttEndpointManager(MqttInboundProperties props,
                                                   MqttProfileRegistry profileRegistry,
                                                   VehicleIdentityResolver identityResolver,
                                                   Dispatcher dispatcher) {
        return new MqttEndpointManager(props, profileRegistry, identityResolver, dispatcher);
    }

    @Bean
    @ConditionalOnProperty(prefix = "lingniu.ingest.mqtt",
            name = "auto-startup",
            havingValue = "true",
            matchIfMissing = true)
    public ApplicationRunner mqttEndpointStartupRunner(MqttEndpointManager manager) {
        return args -> manager.start();
    }
}
