package com.inkasso.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.inkasso.adapter.AvoidRepeatableCommitCheckBean;
import com.inkasso.config.convert.DateConverter;
import com.inkasso.config.json.FastJsonSerializerFeatureCompatibleForJackson;
import com.inkasso.config.json.SerializerFeature;
import com.inkasso.config.properties.FileUploadProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.text.DateFormat;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author 张超
 * @date 2021/9/22
 */
@Configuration
public class MyWebConfig implements WebMvcConfigurer {

  @Autowired
  private Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder;

  @Autowired
  private FileUploadProperties fileUploadProperties;


  @Bean
  public AvoidRepeatableCommitCheckBean AvoidRepeatableCommitCheckBean(){
    return new AvoidRepeatableCommitCheckBean();
  }

  @Bean
  public ThreadPoolTaskExecutor defaultThreadPool(){

    ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
    //核心线程数量
    threadPoolTaskExecutor.setCorePoolSize(3);
    //最大线程数量
    threadPoolTaskExecutor.setMaxPoolSize(10);
    //队列中最大任务数
    threadPoolTaskExecutor.setQueueCapacity(3);
    //线程名称前缀
    threadPoolTaskExecutor.setThreadNamePrefix("卡服宝线程池-");
    //当达到最大线程数时如何处理新任务
    threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    //线程空闲后最大存活时间
    threadPoolTaskExecutor.setKeepAliveSeconds(60);
    //初始化线程池
    threadPoolTaskExecutor.initialize();

    return threadPoolTaskExecutor;

  }


  @Bean
  public MappingJackson2HttpMessageConverter mappingJsonpHttpMessageConverter() {

    ObjectMapper mapper = jackson2ObjectMapperBuilder.build();
    //jackson2ObjectMapperBuilder.serializerByType(Long.TYPE, ToStringSerializer.instance);  无效
    // ObjectMapper为了保障线程安全性，里面的配置类都是一个不可变的对象
    // 所以这里的setDateFormat的内部原理其实是创建了一个新的配置类
    DateFormat dateFormat = mapper.getDateFormat();
    mapper.setDateFormat(new DateConverter(dateFormat));
    mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    SimpleModule simpleModule = new SimpleModule();
//    simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
    //mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
    mapper.registerModule(simpleModule);
    // 分类别处理null
    mapper.setSerializerFactory(mapper.getSerializerFactory().withSerializerModifier(
        new FastJsonSerializerFeatureCompatibleForJackson(SerializerFeature.values())));

    MappingJackson2HttpMessageConverter mappingJsonpHttpMessageConverter = new MappingJackson2HttpMessageConverter(
        mapper);
    return mappingJsonpHttpMessageConverter;
  }

  /**
   * springmvc让程序开发者配置文件上传额外的静态资源服务
   *
   * @param registry
   */
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
//    registry.addResourceHandler("访问的路径").addResourceLocations("上传资源的路径");
//    registry.addResourceHandler("/uploadimg/**").addResourceLocations("file:D://amazingFile//");
    registry.addResourceHandler(fileUploadProperties.getResourcePath())
            .addResourceLocations("file:" + fileUploadProperties.getStoragePath());
  }
}
