package com.brframework.commoncache.config;

import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

/**
 * 缓存管理配置
 * @author xu
 * @date 2019/8/19 14:01
 */
@Configuration
@ConfigurationProperties(prefix = "spring.cache.redis")
@EnableCaching
@Data
public class CacheManagerConfig {

    /**
     * Entry expiration. By default the entries never expire.
     */
    private Duration timeToLive;

    /**
     * Allow caching null values.
     */
    private boolean cacheNullValues = true;

    /**
     * Key prefix.
     */
    private String keyPrefix;

    /**
     * Whether to use the key prefix when writing to Redis.
     */
    private boolean useKeyPrefix = true;


    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheConfiguration config = determineConfiguration();

        RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(config)
                .transactionAware()
                .build();
        return redisCacheManager;
    }


    private RedisCacheConfiguration determineConfiguration() {

        RedisCacheConfiguration config = RedisCacheConfiguration
                .defaultCacheConfig();
        //使用fastjson作为value序列化
        config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericFastJsonRedisSerializer()));
        if (getTimeToLive() != null) {
            config = config.entryTtl(getTimeToLive());
        }
        if (getKeyPrefix() != null) {
            config = config.prefixKeysWith(getKeyPrefix());
        }
        if (!isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }
        if (!isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }
        return config;
    }

}
