/**
 * Dynamic CORS Middleware
 * Intelligently handles CORS based on environment and configuration
 */
import cors from "cors";
import { createLogger } from "../core/logger.js";
const logger = createLogger("CORS");
/**
 * Creates dynamic CORS middleware that intelligently handles origins
 */
export function createDynamicCors(options = {}) {
    const { allowedOrigins = [], devPortRanges = [
        { start: 3000, end: 3010 },
        { start: 5170, end: 5180 },
        { start: 8080, end: 8090 },
    ], commonDevPorts = [3000, 3001, 5173, 5174, 5175, 8080, 8081], credentials = true, customValidator, } = options;
    // Build allowed origins list for development
    const buildDevOrigins = () => {
        const origins = new Set();
        // Add explicitly allowed origins
        allowedOrigins.forEach((origin) => origins.add(origin));
        // Add common development ports
        commonDevPorts.forEach((port) => {
            origins.add(`http://localhost:${port}`);
            origins.add(`http://127.0.0.1:${port}`);
        });
        // Add port ranges
        devPortRanges.forEach((range) => {
            for (let port = range.start; port <= range.end; port++) {
                origins.add(`http://localhost:${port}`);
                origins.add(`http://127.0.0.1:${port}`);
            }
        });
        return Array.from(origins);
    };
    // CORS origin function
    const originFunction = (origin, callback) => {
        // Allow requests with no origin (same-origin, Postman, etc.)
        if (!origin) {
            return callback(null, true);
        }
        // Production mode
        if (process.env.NODE_ENV === "production") {
            // Check against explicit allowed origins
            if (allowedOrigins.length > 0 && allowedOrigins.includes(origin)) {
                return callback(null, true);
            }
            // Check custom validator
            if (customValidator && customValidator(origin)) {
                return callback(null, true);
            }
            // Check if origin matches the app's domain
            const appDomain = process.env.APP_DOMAIN || process.env.PRODUCTION_URL;
            if (appDomain && origin.includes(appDomain)) {
                return callback(null, true);
            }
            // Reject by default in production
            logger.warn(`CORS rejected origin in production: ${origin}`);
            return callback(new Error("Not allowed by CORS"));
        }
        // Development mode - be more permissive
        const devOrigins = buildDevOrigins();
        // Check if origin matches any development origin
        if (devOrigins.some((allowed) => origin.startsWith(allowed))) {
            return callback(null, true);
        }
        // Check if it's any localhost/127.0.0.1 origin
        if (origin.includes("localhost") || origin.includes("127.0.0.1")) {
            logger.debug(`Allowing localhost origin: ${origin}`);
            return callback(null, true);
        }
        // Check custom validator
        if (customValidator && customValidator(origin)) {
            return callback(null, true);
        }
        // Log and allow in development (with warning)
        logger.warn(`CORS: Allowing unrecognized origin in development: ${origin}`);
        return callback(null, true);
    };
    // Create and return configured CORS middleware
    const corsMiddleware = cors({
        origin: originFunction,
        credentials,
        methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
        allowedHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
        exposedHeaders: ["X-Total-Count", "X-Page-Count"],
        maxAge: 86400, // 24 hours
    });
    // Attach the origin function for testing purposes
    corsMiddleware._originFunction = originFunction;
    return corsMiddleware;
}
/**
 * Simple CORS middleware for production with specific domains
 */
export function createProductionCors(allowedDomains) {
    const originFunction = (origin, callback) => {
        if (!origin || allowedDomains.includes(origin)) {
            callback(null, true);
        }
        else {
            callback(new Error("Not allowed by CORS"));
        }
    };
    const corsMiddleware = cors({
        origin: originFunction,
        credentials: true,
    });
    // Attach for testing
    corsMiddleware._originFunction = originFunction;
    return corsMiddleware;
}
/**
 * Permissive CORS for development
 */
export function createDevCors() {
    return createDynamicCors({
        allowedOrigins: [],
        credentials: true,
    });
}
export default createDynamicCors;
//# sourceMappingURL=cors.js.map