#!/usr/bin/env node
import { config } from 'dotenv';
import { existsSync } from 'node:fs';
import { resolve, join } from 'node:path';
import { homedir } from 'node:os';

// Load .env from daemon config dir (global install / daemon mode).
// Loaded first so monorepo .env can override for local dev.
const daemonEnv = join(homedir(), '.config', 'mosaic', 'gateway', '.env');
if (existsSync(daemonEnv)) config({ path: daemonEnv });

// Load .env from monorepo root (cwd is apps/gateway when run via pnpm filter)
config({ path: resolve(process.cwd(), '../../.env') });
config(); // Also load apps/gateway/.env if present (overrides)

import './tracing.js';
import 'reflect-metadata';
import { NestFactory } from '@nestjs/core';
import { Logger, ValidationPipe } from '@nestjs/common';
import { FastifyAdapter, type NestFastifyApplication } from '@nestjs/platform-fastify';
import helmet from '@fastify/helmet';
import { listSsoStartupWarnings } from '@mosaicstack/auth';
import { loadConfig } from '@mosaicstack/config';
import { AppModule } from './app.module.js';
import { mountAuthHandler } from './auth/auth.controller.js';
import { mountMcpHandler } from './mcp/mcp.controller.js';
import { McpService } from './mcp/mcp.service.js';
import { detectAndAssertTier, TierDetectionError } from '@mosaicstack/storage';

async function bootstrap(): Promise<void> {
  const logger = new Logger('Bootstrap');

  if (!process.env['BETTER_AUTH_SECRET']) {
    throw new Error('BETTER_AUTH_SECRET is required');
  }

  // Pre-flight: assert all external services required by the configured tier
  // are reachable. Runs before NestFactory.create() so failures are visible
  // immediately with actionable remediation hints.
  const mosaicConfig = loadConfig();
  try {
    await detectAndAssertTier(mosaicConfig);
  } catch (err) {
    if (err instanceof TierDetectionError) {
      logger.error(`Tier detection failed: ${err.message}`);
      logger.error(`Remediation: ${err.remediation}`);
    }
    throw err;
  }

  for (const warning of listSsoStartupWarnings()) {
    logger.warn(warning);
  }

  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter({ bodyLimit: 1_048_576 }),
  );

  app.enableCors({
    origin: process.env['GATEWAY_CORS_ORIGIN'] ?? 'http://localhost:3000',
    credentials: true,
    methods: ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
  });

  await app.register(helmet as never, { contentSecurityPolicy: false });
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
      forbidNonWhitelisted: true,
      transform: true,
    }),
  );

  mountAuthHandler(app);
  mountMcpHandler(app, app.get(McpService));

  const port = Number(process.env['GATEWAY_PORT'] ?? 14242);
  await app.listen(port, '0.0.0.0');
  logger.log(`Gateway listening on port ${port}`);
}

bootstrap().catch((err: unknown) => {
  const logger = new Logger('Bootstrap');
  logger.error('Fatal startup error', err instanceof Error ? err.stack : String(err));
  process.exit(1);
});
