import 'dotenv/config';
import 'reflect-metadata';
import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import { AppModule } from './app.module';
import { traceMiddleware } from './observability/trace.middleware';
import { RedisIoAdapter } from './realtime/redis-io.adapter';
import { PolicyDeniedFilter } from './platform/policy-denied.filter';

async function bootstrap(): Promise<void> {
  const app = await NestFactory.create(AppModule, { rawBody: true });
  // Express 5 defaults to the 'simple' query parser, which ignores nested params like
  // ?metadata[key]=value — so generic metadata filters would be silently dropped. Use the
  // qs-based 'extended' parser so those parse into a nested object.
  app.getHttpAdapter().getInstance().set('query parser', 'extended');
  app.use(traceMiddleware); // request-scoped trace context + x-trace-id header (P9)
  app.useGlobalPipes(
    new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true }),
  );
  app.useGlobalFilters(new PolicyDeniedFilter()); // fail-closed policy denials → 403
  app.enableCors({ origin: true, credentials: true });

  // Multi-replica realtime: fan socket.io room emits across instances via Redis.
  // Opt-in — without REDIS_URL the default in-memory adapter is used (single instance).
  if (process.env.REDIS_URL) {
    const redisAdapter = new RedisIoAdapter(app, process.env.REDIS_URL);
    await redisAdapter.connect();
    app.useWebSocketAdapter(redisAdapter);
  }

  const port = Number(process.env.PORT ?? 3200);
  await app.listen(port);
  // eslint-disable-next-line no-console
  console.log(`iios-service listening on :${port}`);
}

void bootstrap();
