package com.tykj.workflowcore.model_layer.config;


import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


import javax.persistence.EntityManagerFactory;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.TimeUnit;


/**
 * @Author WWW
 * @Description
 * @Date 10:47 2021/3/26
 * @return
 **/
@Configuration
@EnableCaching
public class MyCacheConfig {

    @Autowired
    EntityManagerFactory entityManagerFactory;

    @Bean
    public CacheManager cacheManager() {
        /*
        api + cache   spring cache + hashmap
        myCode + redis
        spring cache + caffeine
        */
//        SimpleCacheManager cacheManager = new SimpleCacheManager();

        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        Caffeine caffeine = Caffeine.newBuilder()
                /* cache的初始容量值 */
                .initialCapacity(150)
                //maximumSize用来控制cache的最大缓存数量，maximumSize和maximumWeight(最大权重)不可以同时使用，
                .maximumSize(1000)
                //最后一次写入或者访问后过久过期
                .expireAfterAccess(30, TimeUnit.DAYS)
//                //创建或更新之后多久刷新,需要设置cacheLoader
                .refreshAfterWrite(5, TimeUnit.SECONDS);
        cacheManager.setCaffeine(caffeine);
        cacheManager.setCacheLoader(cacheLoader());
        /* 根据名字可以创建多个cache，但是多个cache使用相同的策略 */
        cacheManager.setCacheNames(Arrays.asList("tableInfos"));
        //是否允许值为空
        cacheManager.setAllowNullValues(false);
        /* cacheManager.setCaches(Collections.singletonList(new ConcurrentMapCache("tableInfos"))); */
        return cacheManager;
    }


    @Bean
    public CacheLoader cacheLoader(){
        return new CacheLoader() {
            @Nullable
            @Override
            public Object load(@NonNull Object o) {
                return null;
            }

            @Nullable
            @Override
            public Object reload(@NonNull Object key, @NonNull Object oldValue) {
                return oldValue;
            }
        };
    }

    @Bean
    public MetadataSources metadataSources(){
        SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
        StandardServiceRegistry serviceRegistry = sessionFactory.getSessionFactoryOptions().getServiceRegistry();
        return new MetadataSources(serviceRegistry);
    }

}
