package com.config;


import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.io.IOException;
import java.util.List;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    /**
     * 创建专门用于 HTTP 请求的 ObjectMapper
     */
    @Bean
    public ObjectMapper httpObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();

        // 注册 Java 8 日期时间支持
        mapper.registerModule(new JavaTimeModule());

        // 禁用将日期序列化为时间戳
        mapper.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

        // 注册达梦 JDBC 安全序列化器 — 拦截 dm.jdbc.* 类，直接返回 null 防止循环引用 StackOverflow
        SimpleModule dmSafeModule = new SimpleModule("dm-safe");
        dmSafeModule.setSerializerModifier(new BeanSerializerModifier() {
            @Override
            public JsonSerializer<?> modifySerializer(SerializationConfig config,
                                                       BeanDescription beanDesc,
                                                       JsonSerializer<?> serializer) {
                if (beanDesc.getBeanClass().getName().startsWith("dm.jdbc.")) {
                    return new JsonSerializer<Object>() {
                        @Override
                        public void serialize(Object value, JsonGenerator gen,
                                            SerializerProvider serializers) throws IOException {
                            gen.writeNull();
                        }

                        @Override
                        public void serializeWithType(Object value, JsonGenerator gen,
                                            SerializerProvider serializers, TypeSerializer typeSer) throws IOException {
                            gen.writeNull();
                        }
                    };
                }
                return serializer;
            }
        });
        mapper.registerModule(dmSafeModule);

        // 忽略未知属性
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        // 确保禁用所有类型信息
        mapper.deactivateDefaultTyping();

        return mapper;
    }

    /**
     * 创建 HTTP 消息转换器
     */
    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        return new MappingJackson2HttpMessageConverter(httpObjectMapper());
    }

    /**
     * 注册消息转换器到 Spring MVC
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 将 Jackson 转换器添加到转换器列表的开头
        converters.add(0, mappingJackson2HttpMessageConverter());
    }
}