//go:build test && !dev

package mw

import (
	"testing"
	"time"

	"crussell/clock"
)

// TestProgressiveRateLimiter_SingleRequest verifies no delay for first request.
func TestProgressiveRateLimiter_SingleRequest(t *testing.T) {
	prl := NewProgressiveRateLimiter()
	delay := prl.Check("192.168.1.1")
	if delay != 0 {
		t.Errorf("expected 0 delay for first request, got %d", delay)
	}
}

// TestProgressiveRateLimiter_BurstAllowsPageLoad verifies 15 requests in 5s are OK.
func TestProgressiveRateLimiter_BurstAllowsPageLoad(t *testing.T) {
	prl := NewProgressiveRateLimiter()
	ip := "192.168.1.1"

	for i := 0; i < 15; i++ {
		delay := prl.Check(ip)
		if delay != 0 {
			t.Errorf("expected 0 delay for request %d (within burst), got %d", i+1, delay)
		}
	}
}

// TestProgressiveRateLimiter_ExcessBurstDelays verifies 35+ requests in 5s get delayed.
func TestProgressiveRateLimiter_ExcessBurstDelays(t *testing.T) {
	prl := NewProgressiveRateLimiter()
	ip := "192.168.1.1"

	delayed := false
	for i := 0; i < 35; i++ {
		delay := prl.Check(ip)
		if delay > 0 {
			delayed = true
		}
	}

	if !delayed {
		t.Error("expected at least one delay after 35 burst requests")
	}
}

// TestProgressiveRateLimiter_SustainedAllowsNormal verifies 30 requests
// spread over 60 seconds are not delayed.
func TestProgressiveRateLimiter_SustainedAllowsNormal(t *testing.T) {
	prl := NewProgressiveRateLimiter()
	ip := "192.168.1.2"

	for i := 0; i < 30; i++ {
		prl.mu.Lock()
		state, exists := prl.requests[ip]
		if !exists {
			prl.requests[ip] = &ipProgressiveState{
				timestamps: []time.Time{clock.Now().Add(-time.Duration(60-i*2) * time.Second)},
			}
			prl.mu.Unlock()
			continue
		}
		state.timestamps = append(state.timestamps, clock.Now().Add(-time.Duration(60-i*2)*time.Second))
		prl.mu.Unlock()
	}

	delay := prl.Check(ip)
	if delay != 0 {
		t.Errorf("expected 0 delay for 30 sustained requests over 60s, got %d", delay)
	}
}

// TestProgressiveRateLimiter_ExcessSustainedDelays verifies 130+ requests
// in 60s triggers delay.
func TestProgressiveRateLimiter_ExcessSustainedDelays(t *testing.T) {
	prl := NewProgressiveRateLimiter()
	ip := "192.168.1.3"

	now := clock.Now()
	prl.mu.Lock()
	state := &ipProgressiveState{timestamps: make([]time.Time, 130)}
	for i := 0; i < 130; i++ {
		state.timestamps[i] = now.Add(-time.Duration(60-i/3) * time.Second)
	}
	prl.requests[ip] = state
	prl.mu.Unlock()

	delay := prl.Check(ip)
	if delay == 0 {
		t.Error("expected delay > 0 for 130 sustained requests")
	}
}

// TestProgressiveRateLimiter_DifferentIPs verifies rate limiter
// tracks IPs independently.
func TestProgressiveRateLimiter_DifferentIPs(t *testing.T) {
	prl := NewProgressiveRateLimiter()

	for i := 0; i < 40; i++ {
		prl.Check("10.0.0.1")
	}

	delay := prl.Check("10.0.0.2")
	if delay != 0 {
		t.Errorf("expected 0 delay for separate IP, got %d", delay)
	}
}
