// dd-trace must be initialized before any other module is loaded for auto-instrumentation
import '@shieldai/monitoring/datadog-init';
import Fastify from "fastify";
import cors from "@fastify/cors";
import helmet from "@fastify/helmet";
import sensible from "@fastify/sensible";
import { extractOrGenerateRequestId } from "@shieldai/types";
import { authMiddleware } from "./middleware/auth.middleware";
import { errorHandlingMiddleware } from "./middleware/error-handling.middleware";
import { loggingMiddleware } from "./middleware/logging.middleware";
import { monitoringMiddleware } from "./middleware/monitoring.middleware";
import { darkwatchRoutes } from "./routes/darkwatch.routes";
import { voiceprintRoutes } from "./routes/voiceprint.routes";
import { correlationRoutes } from "./routes/correlation.routes";
import { extensionRoutes } from "./routes/extension.routes";
import { waitlistRoutes } from "./routes/waitlist.routes";
import { blogRoutes } from "./routes/blog.routes";
import { blogAdminRoutes } from "./routes/blog-admin.routes";
import { captureSentryError } from "@shieldai/monitoring";
import { getCorsOrigins } from "./config/api.config";

const app = Fastify({
  logger: {
    level: process.env.LOG_LEVEL || "info",
  },
});

async function bootstrap() {
  const corsOrigins = getCorsOrigins();
  await app.register(cors, { origin: corsOrigins });
  await app.register(helmet);
  await app.register(sensible);

  // Register auth middleware to populate request.user
  await app.register(authMiddleware);

  // Register logging middleware (request/response logging)
  await app.register(loggingMiddleware);

  // Register monitoring middleware (CloudWatch metrics)
  await app.register(monitoringMiddleware);

  // Register error handling middleware (Sentry integration)
  await app.register(errorHandlingMiddleware);

  app.addHook("onRequest", async (request, _reply) => {
    const requestId = extractOrGenerateRequestId(request.headers);
    request.id = requestId;
    const pinoLog = request.log as typeof request.log & { bindings?: Record<string, string>; bindActive?: () => void };
    pinoLog.bindings = { requestId };
    pinoLog.bindActive?.();
    request.headers["x-request-id"] = requestId;
  });

  await app.register(darkwatchRoutes);
  await app.register(voiceprintRoutes);
  await app.register(correlationRoutes);
  await app.register(extensionRoutes, { prefix: '/extension' });
  await app.register(waitlistRoutes);
  await app.register(blogRoutes, { prefix: '/blog' });
  await app.register(blogAdminRoutes);

  app.get("/health", async () => ({ status: "ok", timestamp: new Date().toISOString() }));

  try {
    await app.listen({ port: parseInt(process.env.PORT || "3000", 10), host: "0.0.0.0" });
    app.log.info(`Server listening on port ${process.env.PORT || 3000}`);
  } catch (err) {
    app.log.error(err);
    captureSentryError(err as Error, { context: "server_startup" });
    process.exit(1);
  }
}

bootstrap();
