package com.malk.core;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.LRUCache;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

/**
 * Nonce 去重缓存（capability: replay-guard）
 *
 * <p>基于 Hutool {@link LRUCache} 实现（兼顾容量上限 + 过期）。
 * TTL = {@code mjava.auth.window + 30s}。
 * 单 JVM 实例生效；多实例场景需升级分布式缓存（独立 change 评估）。</p>
 */
@Component
public class NonceCache {

    @Value("${mjava.auth.window:300}")
    private long windowSeconds;

    @Value("${mjava.auth.nonce-cache-size:10000}")
    private int capacity;

    private LRUCache<String, Long> cache;

    @PostConstruct
    public void init() {
        long ttlMs = TimeUnit.SECONDS.toMillis(windowSeconds + 30);
        this.cache = CacheUtil.newLRUCache(capacity, ttlMs);
    }

    /**
     * 首次写入 nonce 返回 true；若已存在（在 TTL 内重放）返回 false。
     *
     * @param nonce 请求 Nonce
     * @return true=首次，false=重放
     */
    public synchronized boolean putIfAbsent(String nonce) {
        if (cache.containsKey(nonce)) {
            return false;
        }
        cache.put(nonce, System.currentTimeMillis());
        return true;
    }

    /**
     * 当前缓存条目数（监控用）
     */
    public int size() {
        return cache.size();
    }
}
