#!/usr/bin/env node
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const dotenv = require("dotenv");
dotenv.config();
const tracing_1 = require("./tracing");
const undici_1 = require("undici");
const core_1 = require("@nestjs/core");
const app_module_1 = require("./app.module");
const http_exception_filter_1 = require("./http-exception.filter");
const common_1 = require("@nestjs/common");
const seeding_service_1 = require("./seeding/seeding.service");
const timeout_interceptor_1 = require("./timeout.interceptor");
const sessions_service_1 = require("./sessions/sessions.service");
const express_1 = require("express");
const app_service_1 = require("./app.service");
const net = require("net");
const platform_ws_1 = require("@nestjs/platform-ws");
const swagger_1 = require("@nestjs/swagger");
function isPortInUse(port) {
    return new Promise((resolve) => {
        const server = net.createServer();
        server.once('error', (err) => {
            if (err.code === 'EADDRINUSE') {
                resolve(true);
            }
        });
        server.once('listening', () => {
            server.close(() => {
                resolve(false);
            });
        });
        server.listen(port);
    });
}
async function findAvailablePort(startPort) {
    let port = startPort;
    while (await isPortInUse(port)) {
        port++;
    }
    return port;
}
async function bootstrap() {
    await (0, tracing_1.initTracing)();
    (0, undici_1.setGlobalDispatcher)(new undici_1.Agent({
        headersTimeout: 1_200_000,
        bodyTimeout: 1_200_000,
        connect: { timeout: 60_000 },
    }));
    if (process.env.REPOBURG_PROJECT_PATH) {
        try {
            process.chdir(process.env.REPOBURG_PROJECT_PATH);
        }
        catch (err) {
            console.error(`[FATAL] Could not change directory to specified path: ${process.env.REPOBURG_PROJECT_PATH}`);
            console.error(err);
            process.exit(1);
        }
    }
    const app = await core_1.NestFactory.create(app_module_1.AppModule);
    app.useWebSocketAdapter(new platform_ws_1.WsAdapter(app));
    app.use((0, express_1.json)({ limit: '50mb' }));
    app.use((0, express_1.urlencoded)({ extended: true, limit: '50mb' }));
    const seeder = app.get(seeding_service_1.SeedingService);
    await seeder.seed();
    const sessionsService = app.get(sessions_service_1.SessionsService);
    await sessionsService.resetAllIsRunning();
    app.enableCors({
        origin: '*',
        methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
        credentials: true,
    });
    app.useGlobalInterceptors(new timeout_interceptor_1.TimeoutInterceptor());
    app.useGlobalFilters(new http_exception_filter_1.AllExceptionsFilter());
    app.useGlobalPipes(new common_1.ValidationPipe({
        whitelist: true,
        forbidNonWhitelisted: true,
        transform: true,
    }));
    const preferredPort = process.env.PORT
        ? parseInt(process.env.PORT, 10)
        : 3000;
    const port = await findAvailablePort(preferredPort);
    const appService = app.get(app_service_1.AppService);
    appService.setPort(port);
    const config = new swagger_1.DocumentBuilder()
        .setTitle('Repoburg API')
        .setDescription('API documentation for Repoburg backend')
        .setVersion('1.0')
        .build();
    const document = swagger_1.SwaggerModule.createDocument(app, config);
    swagger_1.SwaggerModule.setup('docs/openapi', app, document);
    await app.listen(port);
    console.log(`Application is running on: ${await app.getUrl()}`);
    console.log(`Repoburg backend serving project from: ${process.cwd()}`);
    console.log(`Open in browser: http://localhost:3001?bport=${port}`);
    console.log(`API Docs: http://localhost:${port}/docs/openapi`);
}
bootstrap();
//# sourceMappingURL=main.js.map