import "reflect-metadata";
import { join } from "path";
import { NestFactory } from "@nestjs/core";
import { NestExpressApplication } from "@nestjs/platform-express";
import { ConfigService } from "@nestjs/config";
import { ValidationPipe } from "@nestjs/common";
import cookieParser from "cookie-parser";
import compression from "compression";
import helmet from "helmet";
import { AppModule } from "./app.module";

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  const config = app.get(ConfigService);

  // Only trust X-Forwarded-For when we know there's an actual reverse proxy
  // in front of us (cPanel/Passenger in production — see .env.example).
  // Blindly trusting it with no real proxy would let any client spoof its
  // own IP and dodge rate limiting; not trusting it when there IS a proxy
  // makes every visitor look like the proxy's IP, which breaks rate
  // limiting (and analytics) the other way by lumping everyone into one
  // bucket.
  if (config.get<string>("TRUST_PROXY") === "true") {
    app.set("trust proxy", 1);
  }

  // Security headers (X-Content-Type-Options, X-Frame-Options, HSTS, etc.).
  // The uploads dir and every JSON response are served cross-origin from
  // the frontend's domain, so the default same-origin Cross-Origin-Resource-
  // Policy would get the browser to block them — relax it to cross-origin.
  // CSP is left off: this is a pure JSON/asset API, not an HTML-rendering
  // server, so there's no document context for a CSP to protect.
  app.use(
    helmet({
      contentSecurityPolicy: false,
      crossOriginResourcePolicy: { policy: "cross-origin" },
    }),
  );
  app.use(compression());

  // Uploaded content images (see ContentController's /content/upload) —
  // served directly off disk, no CDN/S3 needed on plain cPanel hosting.
  // immutable + long max-age is safe: filenames are random UUIDs, so a
  // changed image is a new URL, never the same URL with different bytes.
  app.useStaticAssets(join(process.cwd(), "uploads"), {
    prefix: "/uploads/",
    maxAge: "365d",
    immutable: true,
  });

  app.use(cookieParser());
  app.useGlobalPipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true }));

  const origins = (config.get<string>("CORS_ORIGINS") ?? "http://localhost:3000")
    .split(",")
    .map((o) => o.trim())
    .filter(Boolean);
  app.enableCors({ origin: origins, credentials: true });

  const port = Number(config.get<string>("PORT") ?? 4000);
  await app.listen(port);
  // eslint-disable-next-line no-console
  console.log(`Infobahn admin API listening on :${port}`);
}

bootstrap();
