import { randomUUID } from 'node:crypto';

import cookie from '@fastify/cookie';
import websocket from '@fastify/websocket';
import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { Logger } from 'nestjs-pino';

import { validateConfig } from '@hexahost/config';

import { AppModule } from './app.module';
import { Rfc7807ExceptionFilter } from './common/filters/rfc7807-exception.filter';

async function bootstrap(): Promise<void> {
  const config = validateConfig();

  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter({
      genReqId: () => randomUUID(),
      requestIdHeader: 'x-request-id',
      requestIdLogLabel: 'requestId',
    }),
    {
      bufferLogs: true,
    },
  );

  app.useLogger(app.get(Logger));
  app.setGlobalPrefix('api/v1');
  app.enableCors({
    origin: config.APP_URL,
    credentials: true,
  });
  app.useGlobalFilters(new Rfc7807ExceptionFilter());

  await app.register(cookie, {
    secret: config.SESSION_SECRET,
  });

  await app.register(websocket);

  const swaggerConfig = new DocumentBuilder()
    .setTitle(config.APP_NAME)
    .setDescription('HexaHost GameCloud REST API')
    .setVersion('0.0.0')
    .addServer(config.API_URL)
    .build();

  const document = SwaggerModule.createDocument(app, swaggerConfig);
  SwaggerModule.setup('api/v1/docs', app, document);

  await app.listen(config.API_PORT, '0.0.0.0');
}

void bootstrap();
