package com.ningdatech.carapi.sys.helper;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.Maps;
import com.ningdatech.carapi.user.entity.NdUserInfo;
import com.ningdatech.carapi.user.mapper.NdUserInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * UserCacheHelper
 * </p>
 *
 * @author PoffyZhang
 * @since 09:01 2022/11/29
 */
@Slf4j
@Component
public class UserCacheHelper implements InitializingBean {

    private LoadingCache<Long, NdUserInfo> userCache;

    //==================================================================================================================

    private Map<Long, NdUserInfo> userMap = Maps.newHashMap();

    @Resource
    private NdUserInfoMapper userInfoMapper;

    @Override
    public void afterPropertiesSet() {
        userCache = Caffeine.newBuilder()
                // 需避免刷新过于频繁
                .refreshAfterWrite(10, TimeUnit.MINUTES)
//                .maximumSize(50000)
                .build(new CacheLoader<Long, NdUserInfo>() {

                    @Override
                    public NdUserInfo load(Long id) throws Exception {
                        NdUserInfo user = userInfoMapper.selectById(id);
                        if(Objects.isNull(user)){
                            log.info("加载用户信息失败: {}",id);
                            return null;
                        }
                        return user;
                    }

                    @Override
                    public Map<Long, NdUserInfo>  loadAll(Iterable<? extends Long> keys) throws Exception  {
                        List<NdUserInfo> users = userInfoMapper.selectList(Wrappers.lambdaQuery(NdUserInfo.class).in(NdUserInfo::getId,keys));
                        if(CollUtil.isEmpty(users)){
                            log.info("加载用户信息失败: 信息为空");
                            return Collections.emptyMap();
                        }
                        Map<Long,NdUserInfo> map = users.stream()
                                .collect(Collectors.toMap(c -> c.getId(),c -> c));
                        return map;
                    }


                });

        List<NdUserInfo> users = userInfoMapper.selectList(Wrappers.lambdaQuery(NdUserInfo.class));
        if(CollUtil.isEmpty(users)){
            log.info("加载用户信息失败: 为空");
            return;
        }
        users.stream().forEach(u -> {
            userCache.put(u.getId(),u);
            userMap.put(u.getId(),u);
        });
    }

    public Collection<NdUserInfo> all(){
        return userCache.asMap().values();
    }

    /**
     * 获取信息
     * @param id
     * @return
     */
    public NdUserInfo getById(Long id) {
        if(Objects.isNull(id)){
            return null;
        }
        return userCache.get(id);
    }

    /**
     * 获取当前信息
     * @return
     */
    public Map<Long,NdUserInfo> asMap() {
        return userCache.asMap();
    }

    public void refresh(Long id) {
        userCache.refresh(id);
        NdUserInfo userInfo = userCache.get(id);
        if(Objects.nonNull(userInfo)){
            userMap.put(userInfo.getId(),userInfo);
        }
    }

    public void refresh(List<Long> ids) {
        if(CollUtil.isNotEmpty(ids)){
            ids.forEach(id -> {
                refresh(id);
            });
        }
    }
}
