/**
 * Vite Dev Server (Primary)
 *
 * Starts Vite as the primary dev server on the user-facing port.
 * Serves frontend assets natively and proxies API/WebSocket requests
 * to the Bun backend server.
 */
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
    if (typeof path === "string" && /^\.\.?\//.test(path)) {
        return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
            return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
        });
    }
    return path;
};
import { join } from 'node:path';
import { createRequire } from 'node:module';
import { createServer as createNetServer } from 'node:net';
import { generateAssetServerConfig } from './vite-asset-server-config';
/**
 * Check if a specific port is available on the given host.
 */
function isPortAvailable(port, host) {
    return new Promise((resolve) => {
        const server = createNetServer();
        server.once('error', () => {
            resolve(false);
        });
        server.listen(port, host, () => {
            server.close(() => {
                resolve(true);
            });
        });
    });
}
/**
 * Find an available port starting from the preferred port.
 * Tries incrementing ports up to maxAttempts times.
 *
 * Exported so the dev command can pre-resolve the Vite port before
 * starting the Bun backend (env vars like AGENTUITY_BASE_URL need
 * the real port before Bun initializes CORS).
 */
export async function findAvailablePort(preferredPort, host = '127.0.0.1', maxAttempts = 20) {
    for (let attempt = 0; attempt < maxAttempts; attempt++) {
        const port = preferredPort + attempt;
        const available = await isPortAvailable(port, host);
        if (available) {
            return port;
        }
    }
    throw new Error(`Could not find an available port after ${maxAttempts} attempts starting from ${preferredPort}`);
}
/**
 * Start Vite asset server on a dynamically-chosen port
 * Returns the server instance and the actual port number
 */
export async function startViteAssetServer(options) {
    const { rootDir, logger, workbenchPath, port: preferredPort = 3500, backendPort, routePaths, liveHostname, } = options;
    logger.debug('Starting Vite dev server (primary, proxying backend on port %d)...', backendPort);
    // Find an available port for the user-facing Vite server
    const availablePort = await findAvailablePort(preferredPort, '127.0.0.1');
    if (availablePort !== preferredPort) {
        logger.info(`Port ${preferredPort} is in use, using port ${availablePort} for Vite dev server`);
    }
    // Generate config with proxy to Bun backend
    const config = await generateAssetServerConfig({
        rootDir,
        logger,
        workbenchPath,
        port: availablePort,
        backendPort,
        routePaths,
        liveHostname,
    });
    // Dynamically import vite from the project's node_modules
    // This ensures we resolve from the target project directory, not the CWD
    const projectRequire = createRequire(join(rootDir, 'package.json'));
    const { createServer } = await import(__rewriteRelativeImportExtension(projectRequire.resolve('vite')));
    // Create Vite server with config
    const server = await createServer(config);
    // Start listening with timeout to prevent hangs
    const STARTUP_TIMEOUT_MS = 30000; // 30 seconds
    try {
        await Promise.race([
            server.listen(),
            new Promise((_, reject) => {
                const timeoutId = setTimeout(() => {
                    reject(new Error(`Vite asset server failed to start within ${STARTUP_TIMEOUT_MS / 1000}s`));
                }, STARTUP_TIMEOUT_MS);
                // Clean up timeout when listen succeeds (via finally in the outer try)
                server.httpServer?.once('listening', () => clearTimeout(timeoutId));
            }),
        ]);
    }
    catch (error) {
        // Attempt to close the server on failure
        try {
            await server.close();
        }
        catch {
            // Ignore close errors
        }
        throw error;
    }
    // Port was pre-verified and strictPort:true ensures Vite uses exactly this port
    const actualPort = availablePort;
    logger.debug(`Vite dev server running on port ${actualPort} (primary)`);
    logger.debug(`Frontend: HMR, React transformation, source maps (native)`);
    logger.debug(`Backend: proxying to Bun on port ${backendPort}`);
    return { server, port: actualPort };
}
//# sourceMappingURL=vite-asset-server.js.map