"use strict";
/**
 * Custom Next.js Server with WebSocket Support
 * Integrates WebSocket server for real-time communication
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// IMPORTANT: Register uncaught exception handler FIRST, before any imports
// This ensures we catch WebSocket frame errors before other handlers
process.on('uncaughtException', (error) => {
    // Check for WebSocket-related errors that are non-fatal
    const isWebSocketError = error.code === 'WS_ERR_INVALID_UTF8' ||
        error.code === 'WS_ERR_INVALID_CLOSE_CODE' ||
        error.code === 'WS_ERR_UNEXPECTED_RSV_1' ||
        error.code === 'ECONNRESET' ||
        error.code === 'EPIPE' ||
        (error instanceof RangeError && error.message?.includes('Invalid WebSocket frame')) ||
        error.message?.includes('write after end');
    if (isWebSocketError) {
        // Silently ignore these non-fatal WebSocket frame errors
        // They commonly occur when mobile browsers send malformed close frames
        return;
    }
    // For other uncaught exceptions, log and exit
    console.error('Uncaught exception:', error);
    process.exit(1);
});
const http_1 = require("http");
const url_1 = require("url");
const next_1 = __importDefault(require("next"));
const ws_server_1 = require("./src/lib/ws-server");
const worktrees_1 = require("./src/lib/worktrees");
const db_instance_1 = require("./src/lib/db-instance");
const response_poller_1 = require("./src/lib/response-poller");
const auto_yes_manager_1 = require("./src/lib/auto-yes-manager");
const db_migrations_1 = require("./src/lib/db-migrations");
const env_1 = require("./src/lib/env");
const dev = process.env.NODE_ENV !== 'production';
const hostname = (0, env_1.getEnvByKey)('CM_BIND') || '127.0.0.1';
const port = parseInt((0, env_1.getEnvByKey)('CM_PORT') || '3000', 10);
// Create Next.js app
const app = (0, next_1.default)({ dev, hostname, port });
const handle = app.getRequestHandler();
app.prepare().then(() => {
    // Create HTTP server
    const server = (0, http_1.createServer)(async (req, res) => {
        try {
            const parsedUrl = (0, url_1.parse)(req.url, true);
            await handle(req, res, parsedUrl);
        }
        catch (err) {
            console.error('Error handling request', err);
            res.statusCode = 500;
            res.end('Internal Server Error');
        }
    });
    // Setup WebSocket server
    (0, ws_server_1.setupWebSocket)(server);
    // Scan and sync worktrees on startup
    async function initializeWorktrees() {
        try {
            // Run database migrations first
            console.log('Running database migrations...');
            const db = (0, db_instance_1.getDbInstance)();
            (0, db_migrations_1.runMigrations)(db);
            // Get repository paths from environment variables
            const repositoryPaths = (0, worktrees_1.getRepositoryPaths)();
            if (repositoryPaths.length === 0) {
                console.warn('Warning: No repository paths configured');
                console.warn('Set WORKTREE_REPOS (comma-separated) or MCBD_ROOT_DIR');
                return;
            }
            console.log(`Configured repositories: ${repositoryPaths.length}`);
            repositoryPaths.forEach((path, i) => {
                console.log(`  ${i + 1}. ${path}`);
            });
            // Scan all repositories
            const worktrees = await (0, worktrees_1.scanMultipleRepositories)(repositoryPaths);
            // Sync to database
            (0, worktrees_1.syncWorktreesToDB)(db, worktrees);
            console.log(`✓ Total: ${worktrees.length} worktree(s) synced to database`);
        }
        catch (error) {
            console.error('Error initializing worktrees:', error);
        }
    }
    server.listen(port, async (err) => {
        if (err)
            throw err;
        console.log(`> Ready on http://${hostname}:${port}`);
        console.log(`> WebSocket server ready`);
        // Initialize worktrees after server starts
        await initializeWorktrees();
    });
    // Graceful shutdown with timeout
    let isShuttingDown = false;
    function gracefulShutdown(signal) {
        if (isShuttingDown) {
            console.log('Shutdown already in progress, forcing exit...');
            process.exit(1);
        }
        isShuttingDown = true;
        console.log(`${signal} received: shutting down...`);
        // Stop polling first
        (0, response_poller_1.stopAllPolling)();
        // Issue #138: Stop all auto-yes pollers
        (0, auto_yes_manager_1.stopAllAutoYesPolling)();
        // Close WebSocket connections immediately (don't wait)
        (0, ws_server_1.closeWebSocket)();
        // Force exit after 3 seconds if graceful shutdown fails
        const forceExitTimeout = setTimeout(() => {
            console.log('Graceful shutdown timeout, forcing exit...');
            process.exit(1);
        }, 3000);
        // Try graceful HTTP server close
        server.close(() => {
            clearTimeout(forceExitTimeout);
            console.log('Server closed gracefully');
            process.exit(0);
        });
    }
    process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
    process.on('SIGINT', () => gracefulShutdown('SIGINT'));
});
