import { env } from '@4runr/shared';
function getIdentityKey(request) {
    const apiKey = request.apiKey;
    if (apiKey) {
        return `apikey:${apiKey}`;
    }
    const auth = request.auth || request.user;
    if (auth) {
        if (auth.sub) {
            return `jwt:sub:${auth.sub}`;
        }
        if (auth.tenantId) {
            return `jwt:tenant:${auth.tenantId}`;
        }
    }
    const ip = request.ip || request.headers['x-forwarded-for'] || request.headers['x-real-ip'] || 'unknown';
    return `ip:${ip}`;
}
const buckets = new Map();
function createRateLimiter(max, windowMs) {
    return async function rateLimitMiddleware(request, reply) {
        if (!env.RATE_LIMIT_ENABLED) {
            return;
        }
        const key = getIdentityKey(request);
        const now = Date.now();
        let bucket = buckets.get(key);
        if (!bucket || now >= bucket.resetAt) {
            bucket = {
                count: 0,
                resetAt: now + windowMs
            };
            buckets.set(key, bucket);
        }
        bucket.count++;
        if (bucket.count > max) {
            const retryAfterMs = bucket.resetAt - now;
            reply.status(429).send({
                error: 'rate_limited',
                message: 'Too many requests, please try again later',
                retry_after_ms: retryAfterMs > 0 ? retryAfterMs : windowMs,
                limit: max,
                window_ms: windowMs,
            });
        }
    };
}
export const strictRateLimit = createRateLimiter(Math.floor(env.RATE_LIMIT_MAX / 2), env.RATE_LIMIT_WINDOW_MS);
export const writeRateLimit = createRateLimiter(Math.floor(env.RATE_LIMIT_MAX * 0.75), env.RATE_LIMIT_WINDOW_MS);
export const readRateLimit = createRateLimiter(env.RATE_LIMIT_MAX, env.RATE_LIMIT_WINDOW_MS);
export async function skipRateLimit(request, reply) {
    return;
}
//# sourceMappingURL=rateLimit.js.map