package com.infoepoch.pms.agent.service.auth;

import com.infoepoch.pms.agent.common.utils.component.RedisTool;
import com.infoepoch.pms.agent.properties.SsoProperties;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * Token 防重放服务。
 * <p>
 * 在 Redis 中记录已使用的 Token，确保一次性使用。
 * </p>
 */
@Service
@RequiredArgsConstructor
public class UsedSsoTokenService {

    private static final String KEY_PREFIX = "pms-agent:sso:used:";

    private final RedisTool redisTool;
    private final SsoProperties ssoProperties;

    /**
     * 标记 Token 已被使用。使用 Redis SETNX 保证原子性和幂等性。
     *
     * @param issuer         来源系统标识
     * @param tokenId        Token 唯一标识（jti）
     * @param expireAtMillis Token 过期时间戳（毫秒）
     * @return true 标记成功（首次使用），false 已被使用过
     */
    public boolean markUsed(String issuer, String tokenId, long expireAtMillis) {
        long now = System.currentTimeMillis();
        long ttlMillis = Math.max(1_000L,
                expireAtMillis - now + TimeUnit.SECONDS.toMillis(ssoProperties.getClockSkewSeconds()));
        return redisTool.putIfAbsent(KEY_PREFIX + issuer + ":" + tokenId, "1", ttlMillis, TimeUnit.MILLISECONDS);
    }
}
