package org.lingniu.sdk.config;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.lingniu.sdk.common.redis.RedisCache;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.security.jackson2.SecurityJackson2Modules;
import org.springframework.security.oauth2.client.jackson2.OAuth2ClientJackson2Module;

@Configuration("SdkRedisConfig")
public class SdkRedisConfig {

    @Bean
    @ConditionalOnMissingBean(name = "sdkRedisTemplate")
    @Lazy
    public RedisTemplate<String, Object> sdkRedisTemplate(
            RedisConnectionFactory connectionFactory,
            ObjectMapper objectMapper) {

        // 配置 ObjectMapper 以支持多态类型
        ObjectMapper redisObjectMapper = objectMapper.copy();

        // 启用默认类型信息，用于反序列化
        redisObjectMapper.activateDefaultTyping(
            LaissezFaireSubTypeValidator.instance,
            ObjectMapper.DefaultTyping.NON_FINAL,
            JsonTypeInfo.As.PROPERTY
        );

        // 注册 Spring Security 和 OAuth2 模块
        redisObjectMapper.registerModules(
            SecurityJackson2Modules.getModules(getClass().getClassLoader())
        );
        redisObjectMapper.registerModule(new OAuth2ClientJackson2Module());

        // 创建 RedisTemplate
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        // 使用 StringRedisSerializer 来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());

        // 使用 GenericJackson2JsonRedisSerializer 来序列化和反序列化redis的value值
        GenericJackson2JsonRedisSerializer serializer =
            new GenericJackson2JsonRedisSerializer(redisObjectMapper);

        template.setValueSerializer(serializer);
        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();
        return template;
    }
    @Bean
    @ConditionalOnMissingBean(name="redisCache")
    public RedisCache redisCache(@Qualifier("redisTemplate")RedisTemplate  redisTemplate){
        return new RedisCache(redisTemplate);
    }
}