package com.cool.bang.modules.system.service.impl;

import com.cool.bang.common.tools.secure.JwtUtil;
import com.cool.bang.modules.system.domain.po.User;
import com.cool.bang.modules.system.domain.vo.Token;
import com.cool.bang.modules.system.service.ITokenService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * system token service implementation class
 *
 * @author PeiZhi Guo
 * 2022-4-13 16:10
 */
@Service
public class TokenServiceImpl implements ITokenService {

    private static final String TITLE = "tokens:";

    @Value("${token.expire.seconds}")
    private Integer expireSeconds;

    @Resource
    private RedisTemplate<String, User> redisTemplate;

    @Override
    public Token cacheAndReturnToken(User sysUser) {
        sysUser.setToken(UUID.randomUUID().toString());
        // 插入到 redis
        redisCacheToken(sysUser);
        // 生成 jwtToken
        String jwtToken = JwtUtil.generateToken(sysUser.getToken());
        return new Token(jwtToken, sysUser.getLoginTime());
    }

    @Override
    public User querySysUserByAccessToken(String token) {
        String redisKey = JwtUtil.parseToken(token);
        if (redisKey != null) {
            return redisTemplate.opsForValue().get(TITLE + redisKey);
        }
        return null;
    }

    @Override
    public void refreshCacheToken(User sysUser) {
        redisCacheToken(sysUser);
    }

    @Override
    public boolean deleteCacheToken(String token) {
        String redisKey = JwtUtil.parseToken(token);
        if (redisKey != null) {
            String key = TITLE + redisKey;
            User sysUser = redisTemplate.opsForValue().get(key);
            if (sysUser != null) {
                redisTemplate.delete(key);
                return true;
            }
        }
        return false;
    }

    private void redisCacheToken(User sysUser) {
        sysUser.setLoginTime(System.currentTimeMillis());
        sysUser.setExpireTime(sysUser.getLoginTime() + expireSeconds * 1000);
        redisTemplate.boundValueOps(TITLE + sysUser.getToken())
                .set(sysUser, expireSeconds, TimeUnit.SECONDS);
    }

}
