package com.tasteby.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;

/**
 * #337 — IP 기반 레이트리밋 (방문 카운트 어뷰즈 차단).
 *
 * 단순 Redis SETIFABSENT(SET NX EX) 패턴:
 * - 첫 호출 시 키 등록 + TTL → 허용
 * - TTL 동안 다음 호출은 키 존재로 차단
 *
 * Redis 다운 시 fail-open (true 반환) — 사용자 페이지 로드 우선.
 * 멀티 파드 + Redis 단일 인스턴스 환경에서 자연스럽게 동작.
 */
@Service
public class RateLimitService {

    private static final Logger log = LoggerFactory.getLogger(RateLimitService.class);
    private static final String PREFIX = "ratelimit:visit:";

    private final StringRedisTemplate redis;

    @Value("${app.rate-limit.visit-window-seconds:60}")
    private long visitWindowSeconds;

    public RateLimitService(StringRedisTemplate redis) {
        this.redis = redis;
    }

    /**
     * 단일 IP의 visit 호출 허용 여부.
     * @return true = 허용 (첫 호출 또는 윈도우 만료), false = 차단 (윈도우 안 재호출)
     */
    public boolean tryConsume(String ipKey) {
        try {
            String key = PREFIX + ipKey;
            Boolean ok = redis.opsForValue().setIfAbsent(key, "1", Duration.ofSeconds(visitWindowSeconds));
            return Boolean.TRUE.equals(ok);
        } catch (Exception e) {
            // fail-open: Redis 문제로 통계가 약간 부풀어도 사용자 영향 X
            log.debug("RateLimit error (fail-open): {}", e.getMessage());
            return true;
        }
    }
}
