package ink.wgink.redis.cache.manager.files;

import ink.wgink.exceptions.ParamsException;
import ink.wgink.interfaces.manager.IFilesShowCodeService;
import ink.wgink.pojo.bos.files.FilesShowCode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Set;

/**
 * @ClassName: RedisFilesShowCodeServiceImpl
 * @Description: 文件展示码
 * @Author: wanggeng
 * @Date: 2022/8/1 17:42
 * @Version: 1.0
 */
@Primary
@Component
public class RedisFilesShowCodeService implements IFilesShowCodeService {

    private static final Logger LOG = LoggerFactory.getLogger(RedisFilesShowCodeService.class);
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void addShowCode(String code, String fileId, String fileName) {
        redisTemplate.opsForValue().set(FILE_SHOW_CODE_KEY + fileId, new FilesShowCode(code, fileId, fileName));
    }

    @Override
    public void clearTimeoutShowCode() {
        Set<String> keySet = redisTemplate.keys(FILE_SHOW_CODE_KEY);
        long currentTimeMillis = System.currentTimeMillis();
        Set<String> clearKeys = new HashSet<>(16);
        long clearTimeoutShowCodeCount = 0;
        for (String key : keySet) {
            FilesShowCode showCode = getShowCode(key);
            if (currentTimeMillis - showCode.getLatestUpdateTime() > SHOW_CODE_TIMEOUT_MILLIS) {
                clearKeys.add(FILE_SHOW_CODE_KEY + showCode.getFileId());
            }
        }
        redisTemplate.delete(clearKeys);
        LOG.debug(">>>>>> count of clear timeout show code: {}", clearTimeoutShowCodeCount);
    }

    @Override
    public FilesShowCode getShowCode(String fileId, String code) {
        FilesShowCode showCode = getShowCode(fileId);
        if (showCode == null) {
            throw new ParamsException("查看码不存在");
        }
        if (!StringUtils.equals(showCode.getCode(), code)) {
            throw new ParamsException("查看码不匹配");
        }
        return showCode;
    }

    @Override
    public synchronized FilesShowCode getShowCode(String fileId) {
        FilesShowCode showCode = (FilesShowCode) redisTemplate.opsForValue().get(FILE_SHOW_CODE_KEY + fileId);
        if (showCode != null) {
            showCode.setLatestUpdateTime(System.currentTimeMillis());
            redisTemplate.opsForValue().set(FILE_SHOW_CODE_KEY + fileId, showCode);
        }
        return showCode;
    }

}
