package org.lingniu.sdk.service;

import lombok.extern.slf4j.Slf4j;
import org.lingniu.sdk.common.redis.RedisCache;
import org.lingniu.sdk.constant.CacheConstants;
import org.lingniu.sdk.model.token.AccessTokenInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.util.Map;

@Component
@Slf4j
public class RedisAccessTokenService {

    @Autowired
    private RedisCache redisCache;
    
    private final long ACCESS_TOKEN_EXPIRE = 3600; // 1小时


    /**
     * 存储Access Token到Redis
     */
    public void storeAccessToken(AccessTokenInfo tokenInfo) {
        String key = String.format(CacheConstants.ACCESS_TOKEN_KEY, tokenInfo.getTokenValue());
        try {
            redisCache.setCacheMap(key,tokenInfo.toMap());
            Instant expiresAt = tokenInfo.getExpiresAt();
            long expire = ACCESS_TOKEN_EXPIRE;
            if(expiresAt!=null){
                expire = expiresAt.getEpochSecond() - Instant.now().getEpochSecond();
            }

            redisCache.expire(key,expire);
        } catch (Exception e) {
            log.error("存储Access Token失败", e);
        }
    }
    
    /**
     * 验证Access Token
     */
    public boolean validateAccessToken(String token) {
        String key = String.format(CacheConstants.ACCESS_TOKEN_KEY, token);
        if(!redisCache.hasKey(key)){
            return false;
        }
        AccessTokenInfo accessTokenInfo = getAccessTokenInfo(token);
        if(accessTokenInfo==null){
            return false;
        }
        return accessTokenInfo.isValid();
    }


    /**
     * 删除Access Token
     */
    public boolean removeAccessToken(String token) {
        String key = String.format(CacheConstants.ACCESS_TOKEN_KEY, token);
        return redisCache.deleteObject(key);
    }
    
    /**
     * 获取Access Token信息
     */
    public AccessTokenInfo getAccessTokenInfo(String token) {
        String key = String.format(CacheConstants.ACCESS_TOKEN_KEY, token);
        Map<String, Object> cacheMap = redisCache.getCacheMap(key);
        if(cacheMap!=null){
            return AccessTokenInfo.fromMap(cacheMap);
        }
        return null;
    }

    /**
     * 作废 删除
     * @param tokenInfo
     */
    public void revokeAccessToken(AccessTokenInfo tokenInfo) {
        if(tokenInfo==null){
            return;
        }
        String key = String.format(CacheConstants.ACCESS_TOKEN_KEY, tokenInfo.getTokenValue());
        redisCache.deleteObject(key);
    }
}