package gateway

import (
	"net/http/httptest"
	"testing"
	"time"
)

func TestAuthMiddlewareRejectsAnonymousByDefault(t *testing.T) {
	t.Setenv("GATEWAY_ALLOW_ANONYMOUS", "")
	t.Setenv("GATEWAY_API_KEYS", "")

	auth := NewAuthMiddleware()
	req := httptest.NewRequest("GET", "http://example.com", nil)

	if auth.Authenticate(req) {
		t.Fatal("expected anonymous request to be rejected by default")
	}
}

func TestAuthMiddlewareAllowsConfiguredAPIKey(t *testing.T) {
	t.Setenv("GATEWAY_ALLOW_ANONYMOUS", "")
	t.Setenv("GATEWAY_API_KEYS", "alpha,beta")

	auth := NewAuthMiddleware()
	req := httptest.NewRequest("GET", "http://example.com", nil)
	req.Header.Set("X-API-Key", "beta")

	if !auth.Authenticate(req) {
		t.Fatal("expected configured API key to be accepted")
	}
}

func TestAuthMiddlewareAllowsAnonymousOnlyWhenEnabled(t *testing.T) {
	t.Setenv("GATEWAY_ALLOW_ANONYMOUS", "true")
	t.Setenv("GATEWAY_API_KEYS", "")

	auth := NewAuthMiddleware()
	req := httptest.NewRequest("GET", "http://example.com", nil)

	if !auth.Authenticate(req) {
		t.Fatal("expected anonymous request to be accepted when explicitly enabled")
	}
}

func TestRateLimiterBlocksAfterWindowBudget(t *testing.T) {
	limiter := NewRateLimiter()
	req := httptest.NewRequest("GET", "http://example.com", nil)
	req.RemoteAddr = "203.0.113.10:1234"

	for i := 0; i < gatewayRequestsPerMinute; i++ {
		if !limiter.Allow(req) {
			t.Fatalf("expected request %d to pass", i+1)
		}
	}

	if limiter.Allow(req) {
		t.Fatal("expected request over the per-minute budget to be rejected")
	}
}

func TestRateLimiterResetsAfterWindow(t *testing.T) {
	limiter := NewRateLimiter()
	req := httptest.NewRequest("GET", "http://example.com", nil)
	req.RemoteAddr = "203.0.113.11:1234"

	if !limiter.Allow(req) {
		t.Fatal("expected first request to pass")
	}

	limiter.mu.Lock()
	limiter.limits["203.0.113.11"].resetAt = time.Now().Add(-time.Second)
	limiter.mu.Unlock()

	if !limiter.Allow(req) {
		t.Fatal("expected limiter window to reset")
	}
}
