import { Middleware } from "@lib/router.ts";
import log from "@shared/utils/logger.ts";

const requestCounts: Partial<
    Record<string, { count: number; lastReset: number }>
> = {};

const MAX_REQUESTS_PER_WINDOW = 300;
const RATE_LIMIT_WINDOW = 60000;

const rateLimitMiddleware: Middleware = async (c, next) => {
    const hostnameOpt = c.hostname;

    if (hostnameOpt.isSome()) {
        const hostname = hostnameOpt.value;

        const clientCount = requestCounts[hostname];
        const now = Date.now();

        if (!clientCount || now - clientCount.lastReset > RATE_LIMIT_WINDOW) {
            requestCounts[hostname] = { count: 1, lastReset: now };
        } else if (clientCount.count < MAX_REQUESTS_PER_WINDOW) {
            clientCount.count++;
        } else if (c.preferredType.isSome()) {
            log.info(`client ${hostname} is rate limeted`);
            switch (c.preferredType.value) {
                case "html": {
                    return c.html("429 Too Many Requests", {
                        status: 429,
                    });
                }
                case "json": {
                    return c.json(
                        {
                            err: "429 Too Many Requests",
                        },
                        {
                            status: 429,
                        },
                    );
                }
            }
        } else {
            return new Response("429 Too Many Request", {
                status: 429,
            });
        }
    }
    await next();
};

export default rateLimitMiddleware;
