package com.hdkj.lt.core.sys.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.hdkj.lt.base.constants.RedisKeyConstants;
import com.hdkj.lt.core.sys.dao.SysRolesMapper;
import com.hdkj.lt.core.sys.service.ISysRolesService;
import com.hdkj.lt.utils.cache.RedisRepository;
import com.hdkj.lt.core.sys.model.po.SysRoles;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class SysRolesServiceImpl extends ServiceImpl<SysRolesMapper, SysRoles> implements ISysRolesService {

    private final RedisRepository redisRepository;

    @Override
    public void putAllToCache() {
        redisRepository.del(RedisKeyConstants.CACHE_KEY_ROLES_HASH);
        Map<String, Object> dbMap = super.list().stream().collect(Collectors.toMap(e -> String.valueOf(e.getId()), e -> e));
        redisRepository.putHashValues(RedisKeyConstants.CACHE_KEY_ROLES_HASH, dbMap);
    }

    @Override
    public SysRoles getCacheById(Long roleId) {
        Map<String, Object> cacheMap = redisRepository.getHashValue(RedisKeyConstants.CACHE_KEY_ROLES_HASH);
        SysRoles sysRole = (SysRoles) cacheMap.get(String.valueOf(roleId));
        if (Objects.isNull(sysRole)) {
            sysRole = super.getById(roleId);
            cacheMap.put(String.valueOf(roleId), sysRole);
            redisRepository.putHashValues(RedisKeyConstants.CACHE_KEY_ROLES_HASH, cacheMap);
        }
        return sysRole;
    }

    @Override
    public Map<Long, SysRoles> getCacheMapByIds(Collection<Long> roleIds) {
        Map<Long, SysRoles> resultMap = Maps.newHashMap();
        if (CollectionUtils.isEmpty(roleIds)) {
            return resultMap;
        }
        Map<String, Object> cacheMap = redisRepository.getHashValue(RedisKeyConstants.CACHE_KEY_ROLES_HASH);
        roleIds = roleIds.stream().distinct().collect(Collectors.toList());
        roleIds.forEach(i -> Optional.ofNullable(cacheMap.get(String.valueOf(i))).ifPresent(e -> resultMap.put(i, (SysRoles) e)));
        Set<Long> queriedIds = resultMap.keySet();
        if (CollectionUtils.size(roleIds) != CollectionUtils.size(queriedIds)) {
            List<Long> notFoundIds = (List<Long>) CollectionUtils.removeAll(roleIds, queriedIds);
            Map<Long, SysRoles> dbMap = super.listByIds(notFoundIds).stream().collect(Collectors.toMap(SysRoles::getId, e -> e));
            resultMap.putAll(dbMap);
            cacheMap.putAll(dbMap.entrySet().stream().collect(Collectors.toMap(e -> String.valueOf(e.getKey()), Map.Entry::getValue)));
            redisRepository.putHashValues(RedisKeyConstants.CACHE_KEY_ROLES_HASH, cacheMap);
        }
        return resultMap;
    }

    @Override
    public Set<SysRoles> getCacheSetByIds(Collection<Long> roleIds) {
        Set<SysRoles> resultSet = Sets.newHashSet();
        if (CollectionUtils.isEmpty(roleIds)) {
            return resultSet;
        }
        Map<String, Object> cacheMap = redisRepository.getHashValue(RedisKeyConstants.CACHE_KEY_ROLES_HASH);
        roleIds = roleIds.stream().distinct().collect(Collectors.toList());
        roleIds.forEach(i -> Optional.ofNullable(cacheMap.get(String.valueOf(i))).ifPresent(e -> resultSet.add((SysRoles) e)));
        List<Long> queriedIds = resultSet.stream().map(SysRoles::getId).collect(Collectors.toList());
        if (CollectionUtils.size(roleIds) != CollectionUtils.size(queriedIds)) {
            List<Long> notFoundIds = (List<Long>) CollectionUtils.removeAll(roleIds, queriedIds);
            List<SysRoles> dbList = super.listByIds(notFoundIds);
            resultSet.addAll(dbList);
            Map<Long, SysRoles> dbMap = dbList.stream().collect(Collectors.toMap(SysRoles::getId, e -> e));
            cacheMap.putAll(dbMap.entrySet().stream().collect(Collectors.toMap(e -> String.valueOf(e.getKey()), Map.Entry::getValue)));
            redisRepository.putHashValues(RedisKeyConstants.CACHE_KEY_ROLES_HASH, cacheMap);
        }
        return resultSet;
    }

}
