import { describe, expect, it } from "vitest";
import { rateLimitConfig, TRUSTED_IP_HEADERS } from "./rate-limit";

describe("TRUSTED_IP_HEADERS", () => {
	it("includes Cloudflare connecting headers", () => {
		expect(TRUSTED_IP_HEADERS).toContain("CF-Connecting-IP");
		expect(TRUSTED_IP_HEADERS).toContain("CF-Connecting-IPv6");
	});

	it("includes True-Client-IP", () => {
		expect(TRUSTED_IP_HEADERS).toContain("True-Client-IP");
	});

	it("includes X-Forwarded-For and X-Real-IP", () => {
		expect(TRUSTED_IP_HEADERS).toContain("X-Forwarded-For");
		expect(TRUSTED_IP_HEADERS).toContain("X-Real-IP");
	});

	it("contains exactly the documented set of trusted headers", () => {
		expect(TRUSTED_IP_HEADERS).toHaveLength(5);
	});
});

describe("rateLimitConfig", () => {
	describe("betterAuth.global", () => {
		it("is enabled with sensible defaults", () => {
			expect(rateLimitConfig.betterAuth.global.enabled).toBe(true);
			expect(rateLimitConfig.betterAuth.global.window).toBe(60);
			expect(rateLimitConfig.betterAuth.global.max).toBe(60);
		});

		it("rate-limits sign-in/email more strictly than global default", () => {
			expect(rateLimitConfig.betterAuth.global.customRules["/sign-in/email"]).toEqual({ window: 60, max: 5 });
		});

		it("rate-limits sign-up/email even more strictly", () => {
			expect(rateLimitConfig.betterAuth.global.customRules["/sign-up/email"]).toEqual({ window: 60, max: 3 });
		});

		it("uses long window for password reset to deter abuse", () => {
			expect(rateLimitConfig.betterAuth.global.customRules["/request-password-reset"]).toEqual({
				window: 600,
				max: 3,
			});
		});

		it("rate-limits 2FA verification with longer windows", () => {
			expect(rateLimitConfig.betterAuth.global.customRules["/two-factor/verify-otp"].window).toBe(600);
			expect(rateLimitConfig.betterAuth.global.customRules["/two-factor/verify-totp"].window).toBe(600);
			expect(rateLimitConfig.betterAuth.global.customRules["/two-factor/verify-backup-code"].window).toBe(600);
		});

		it("allows generous polling for username availability", () => {
			expect(rateLimitConfig.betterAuth.global.customRules["/is-username-available"]).toEqual({
				window: 60,
				max: 20,
			});
		});
	});

	describe("betterAuth.oauthProvider", () => {
		it("rate-limits register most strictly", () => {
			expect(rateLimitConfig.betterAuth.oauthProvider.register.max).toBe(5);
		});

		it("allows higher introspect/userinfo throughput", () => {
			expect(rateLimitConfig.betterAuth.oauthProvider.introspect.max).toBe(60);
			expect(rateLimitConfig.betterAuth.oauthProvider.userinfo.max).toBe(60);
		});
	});

	describe("betterAuth.apiKey", () => {
		it("is enabled with hourly window of 1000 requests", () => {
			expect(rateLimitConfig.betterAuth.apiKey.enabled).toBe(true);
			expect(rateLimitConfig.betterAuth.apiKey.timeWindow).toBe(60 * 60 * 1000);
			expect(rateLimitConfig.betterAuth.apiKey.maxRequests).toBe(1000);
		});
	});

	describe("orpc", () => {
		it("limits resume password reset to 5 per 10 minutes", () => {
			expect(rateLimitConfig.orpc.resumePassword).toEqual({ maxRequests: 5, window: 10 * 60 * 1000 });
		});

		it("limits PDF export to 5 per minute", () => {
			expect(rateLimitConfig.orpc.pdfExport).toEqual({ maxRequests: 5, window: 60 * 1000 });
		});

		it("limits AI requests to 20 per minute", () => {
			expect(rateLimitConfig.orpc.aiRequest).toEqual({ maxRequests: 20, window: 60 * 1000 });
		});

		it("provides reasonable mutation throughput for resume edits", () => {
			expect(rateLimitConfig.orpc.resumeMutations).toEqual({ maxRequests: 300, window: 60 * 1000 });
		});

		it("limits storage uploads more strictly than deletes", () => {
			expect(rateLimitConfig.orpc.storageUpload.maxRequests).toBeLessThan(
				rateLimitConfig.orpc.storageDelete.maxRequests,
			);
		});
	});
});
