package com.prudas.app.security;

import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.concurrent.ConcurrentHashMap;

/**
 * In-memory, per-key token-bucket rate limiting (Bucket4j). Keys are
 * typically "{action}:{clientIp}" so each abuse vector (login, contact
 * form, newsletter signup) is limited independently.
 *
 * NOTE: this state is per-JVM. If you scale the backend horizontally
 * behind a load balancer, replace the in-memory map with a shared store
 * (e.g. Bucket4j's Redis/Hazelcast integration) so limits are enforced
 * across all instances — see docs/SECURITY.md.
 */
@Component
public class RateLimitingService {

    private final ConcurrentHashMap<String, Bucket> buckets = new ConcurrentHashMap<>();

    public boolean tryConsume(String key, int permits, Duration window) {
        Bucket bucket = buckets.computeIfAbsent(key, k -> newBucket(permits, window));
        return bucket.tryConsume(1);
    }

    private Bucket newBucket(int permits, Duration window) {
        Bandwidth limit = Bandwidth.classic(permits, io.github.bucket4j.Refill.intervally(permits, window));
        return Bucket.builder().addLimit(limit).build();
    }
}
