import Fastify from 'fastify';
import type { FastifyInstance } from 'fastify';
import pino from 'pino';
import type { McpdConfig } from './config/index.js';
import { registerSecurityPlugins } from './middleware/security.js';
import { errorHandler } from './middleware/error-handler.js';
import { registerHealthRoutes } from './routes/health.js';
import type { HealthDeps } from './routes/health.js';
import type { AuthDeps } from './middleware/auth.js';
import type { AuditDeps } from './middleware/audit.js';
import { errorLogBuffer } from './services/error-log-buffer.js';

export interface ServerDeps {
  health: HealthDeps;
  auth?: AuthDeps;
  audit?: AuditDeps;
}

export async function createServer(config: McpdConfig, deps: ServerDeps): Promise<FastifyInstance> {
  // Tee error/fatal records into an in-memory ring buffer (for `mcpctl errors`)
  // while keeping normal stdout logging intact. Passing a `stream` (vs a full
  // pino instance) keeps Fastify's logger typing stable. multistream routes
  // each record to every stream whose level <= the record's level.
  const app = Fastify({
    logger: {
      level: config.logLevel,
      stream: pino.multistream([
        { stream: process.stdout },
        { level: 'error', stream: errorLogBuffer.stream() },
      ]),
    },
  });

  // Error handler
  app.setErrorHandler(errorHandler);

  // Security plugins
  await registerSecurityPlugins(app, config);

  // Health routes (no auth required)
  registerHealthRoutes(app, deps.health);

  return app;
}
