package com.tzld.piaoquan.recommend.server.config;

import com.google.common.collect.Lists;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

import java.util.concurrent.TimeUnit;

import static java.util.Collections.singletonList;

/**
 * @author dyp
 */
@Configuration
@EnableConfigurationProperties(CustomMongoProperties.class)
public class MongoTemplateConfig {
    @Bean
    public MongoClient mongoClient(CustomMongoProperties properties) {
        MongoClientSettings.Builder builder = MongoClientSettings.builder();

        builder.applyToClusterSettings(settings -> {
            settings.hosts(Lists.newArrayList(
                    new ServerAddress(properties.getClusterHost(), properties.getClusterPort()),
                    new ServerAddress(properties.getSecondaryHost(), properties.getSecondaryPort()),
                    new ServerAddress(properties.getThirdHost(), properties.getThirdPort()),
                    new ServerAddress(properties.getFourthHost(), properties.getFourthPort())));
        });


        builder.credential(MongoCredential.createCredential(properties.getUsername(), properties.getDatabase(), properties.getPassword()));
        builder.applyToConnectionPoolSettings(b -> {
            b.minSize(properties.getMinSize());
            b.maxSize(properties.getMaxSize());
            b.maxWaitTime(properties.getMaxWaitTime(), TimeUnit.MILLISECONDS);
            b.maxConnectionIdleTime(properties.getMaxConnectionIdleTime(), TimeUnit.MILLISECONDS);
            //   b.maxConnectionLifeTime(properties.getMaxConnectionLifeTime(), TimeUnit.MILLISECONDS);
//            b.maintenanceFrequency(10, TimeUnit.MILLISECONDS);
//            b.maintenanceInitialDelay(10, TimeUnit.MILLISECONDS);
//            b.(properties.getMaintenanceFrequency());
//            b.maintenanceInitialDelay();
        });
//        builder.applyToServerSettings(b -> {
//            b.heartbeatFrequency()
//        });
        builder.applyToSocketSettings(b -> {
            b.connectTimeout(properties.getConnectTimeout(), TimeUnit.MILLISECONDS);
            b.readTimeout(properties.getReadTimeout(), TimeUnit.MILLISECONDS);
        });
        return MongoClients.create(builder.build());
    }

    @Bean
    public MongoDatabaseFactory mongoDatabaseFactory(MongoClient client, CustomMongoProperties properties) {
        SimpleMongoClientDatabaseFactory mongoDbFactory = new SimpleMongoClientDatabaseFactory(client,
                properties.getDatabase());

        return mongoDbFactory;
    }

    @Bean(name = "mongoTemplate")
    public MongoTemplate mongoTemplate(MongoDatabaseFactory factory) {

        // 去掉 _class 字段
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
        MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, new MongoMappingContext());
        converter.setTypeMapper(new DefaultMongoTypeMapper(null));

        MongoTemplate mongoTemplate = new MongoTemplate(factory, converter);
        return mongoTemplate;
    }

}
