package com.brilliance.mda.support.cache;

import com.brilliance.mda.runtime.mda.IAuthInfo;
import com.brilliance.mda.runtime.mda.IContext;
import com.brilliance.mda.support.cache.impl.GuavaCache;
import com.brilliance.mda.support.cache.impl.RedisCache;
import com.brilliance.mda.support.cache.serializer.ICacheSerializer;
import com.brilliance.mda.support.cache.serializer.ICacheSerializerEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import javax.annotation.Resource;

@Configuration
public class CacheConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(CacheConfiguration.class);

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Value("${envconfig.cache.serializer:kryo}")
    private String cacheSerializerType;
    @Value("${envconfig.cache.expireAfterAccess:300}")
    private long expireAfterAccess;

    @Bean("ctxCache")
    @ConditionalOnProperty(prefix = "envconfig.cache", name = "type", havingValue = "guava", matchIfMissing = true)
    public ICache<String, IContext> getGuavaCtxCache() {
        //2h timeout
        logger.info("使用Guava作为Context缓存");
        return new GuavaCache<>("CtxCache", expireAfterAccess);
    }

    @Bean("ctxCache")
    @ConditionalOnProperty(prefix = "envconfig.cache", name = "type", havingValue = "redis")
    public ICache<String, IContext> getRedisCtxCache() {
        //2h timeout
        ICacheSerializer cacheSerializer = getCacheSerializer();
        logger.info("使用Redis作为Context缓存,序列化处理器:{}", cacheSerializer.getName());
        this.redisTemplate.setKeySerializer(new StringRedisSerializer());
        this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        return new RedisCache<>("CtxCache", redisTemplate, cacheSerializer, expireAfterAccess);
    }

    @Bean("ctxCacheSerializer")
    public ICacheSerializer getCacheSerializer() {
        return ICacheSerializerEnum.getSerializer(cacheSerializerType);
    }

    @Bean("authCache")
    @ConditionalOnProperty(prefix = "envconfig.cache", name = "type", havingValue = "guava", matchIfMissing = true)
    public ICache<String, IAuthInfo> getGuavaAuthCache() {
        return new GuavaCache<>("AuthCache", expireAfterAccess);
    }

    @Bean("authCache")
    @ConditionalOnProperty(prefix = "envconfig.cache", name = "type", havingValue = "redis")
    public ICache<String, IAuthInfo> getRedisAuthCache() {
        ICacheSerializer cacheSerializer = getCacheSerializer();
        logger.info("使用Redis作为Auth缓存,序列化处理器:{}", cacheSerializer.getName());
        this.redisTemplate.setKeySerializer(new StringRedisSerializer());
        this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        return new RedisCache<>("AuthCache", redisTemplate, cacheSerializer, expireAfterAccess);
    }
}
