package com.ningdatech.pmapi.meta.helper.basic;

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.ningdatech.pmapi.meta.service.IMetaDictionaryService;
import com.ningdatech.pmapi.meta.constant.DictAllTypeEnum;
import com.ningdatech.pmapi.meta.helper.DictionaryCache;
import com.ningdatech.pmapi.meta.model.dto.DictionaryDTO;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author liuxinxin
 * @date 2022/12/22 上午11:03
 */
public abstract class AbstractDictionaryCache implements InitializingBean, DictionaryCache {

    @Autowired
    private IMetaDictionaryService iMetaDictionaryService;

    protected Map<String, DictionaryDTO> dictionaryMap = new ConcurrentHashMap<>();
    protected LoadingCache<String, List<DictionaryDTO>> dictionaryCacheHelper;

    @Override
    public void afterPropertiesSet() {
        dictionaryCacheHelper = Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES)
                .refreshAfterWrite(5, TimeUnit.MINUTES).build(key -> {
                    List<DictionaryDTO> dictionaryDTOList = iMetaDictionaryService.queryAll();
                    dictionaryMap = buildCateMap(dictionaryDTOList);
                    Map<String, List<DictionaryDTO>> dictionaryTypeListMap = dictionaryDTOList.stream().collect(Collectors.groupingBy(DictionaryDTO::getDictionaryType));
                    return dictionaryTypeListMap.get(key);
                });
        warmUp();
    }

    private Map<String, DictionaryDTO> buildCateMap(List<DictionaryDTO> dictionaryDTOList) {
        Map<String, DictionaryDTO> dictionaryDtoMap = new ConcurrentHashMap<>(128);
        dictionaryDTOList.forEach(dictionaryDTO -> dictionaryDtoMap.put(dictionaryDTO.getDictionaryCode(), dictionaryDTO));
        return dictionaryDtoMap;
    }

    private void warmUp() {
        for (DictAllTypeEnum typeEnum : DictAllTypeEnum.values()) {
            dictionaryCacheHelper.get(typeEnum.getKey());
        }
    }

}
