import "reflect-metadata";
import { existsSync } from "node:fs";
import { resolve } from "node:path";
import { NestFactory } from "@nestjs/core";
import { FastifyAdapter, NestFastifyApplication } from "@nestjs/platform-fastify";
import cors from "@fastify/cors";
import { RedisIoAdapter } from "./redis-io.adapter";

function loadEnv() {
  const loadEnvFile = process.loadEnvFile as ((path?: string) => void) | undefined;
  if (!loadEnvFile) return;

  for (const envPath of [resolve(process.cwd(), ".env"), resolve(process.cwd(), "../.env"), resolve(process.cwd(), "../../.env")]) {
    if (existsSync(envPath)) {
      loadEnvFile(envPath);
      return;
    }
  }
}

loadEnv();

async function bootstrap() {
  const { AppModule } = await import("./app.module");
  const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
  // The WebSocketGateway's own `cors` option only covers the Socket.IO
  // namespace — plain HTTP routes on this same Fastify instance (e.g.
  // PresenceController) need their own CORS registration, exactly like
  // apps/api's. Missing this doesn't throw anywhere; it just makes the
  // browser silently fail the cross-origin fetch, which is what happened
  // here before this fix (worked fine via curl, never worked in-browser).
  await app.register(cors, { origin: true });

  const redisIoAdapter = new RedisIoAdapter(app);
  await redisIoAdapter.connectToRedis();
  app.useWebSocketAdapter(redisIoAdapter);

  const port = Number(process.env.GATEWAY_PORT ?? 3002);
  await app.listen(port, "0.0.0.0");
  // eslint-disable-next-line no-console
  console.log(`gateway listening on :${port}`);
}

bootstrap();
