import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from './pips/validate.pipe';
import * as CookieParser from 'cookie-parser';
import * as BodyParser from 'body-parser';
import helmet from 'helmet';
import * as csurf from 'csurf';
import * as fs from 'fs';
import {
  ExpressAdapter,
  NestExpressApplication,
} from '@nestjs/platform-express';
import { join } from 'path';
import { isDev } from './utils/common';
import { initSyncModule } from './utils/async_import';
import { Response } from 'express';
import * as express from 'express';
import * as http from 'http';
import * as https from 'https';
import * as tls from 'tls';

async function bootstrap() {
  await initSyncModule();
  const server = express();
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
    new ExpressAdapter(server),
    {
      logger: ['error', 'warn', 'log'],
    },
  );
  // 全局中间件
  // app.use();
  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.useStaticAssets(join(__dirname, '..', 'screenshot'), {
    prefix: '/screenshot/',
    setHeaders(res: Response, path: string) {
      res.setHeader(
        'Content-Disposition',
        `attachment; filename="${path.slice(path.lastIndexOf('/') + 1)}"`,
      );
      res.setHeader('Content-Transfer-Encoding', 'binary');
    },
  });
  app.useStaticAssets(join(__dirname, '..', 'static'), {
    prefix: '/static/',
  });
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('ejs');
  // cookieParser必须在csurl之前初始化
  app.use(CookieParser());
  app.use(BodyParser.json({ limit: '3mb' }));
  app.use(BodyParser.urlencoded({ limit: '3mb', extended: false }));
  if (!isDev()) {
    app.use(
      csurf({
        cookie: true,
      }),
    );
    app.use(
      helmet({
        crossOriginEmbedderPolicy: false,
        contentSecurityPolicy: false,
      }),
    );
  }
  app.useGlobalPipes(new ValidationPipe());
  return {
    app,
    server,
  };
}

if (process.env.ENV == 'dev') {
  bootstrap().then(({ app }) => {
    app.enableCors();
    app.listen(3000, () => {
      console.log('服务启动在3000端口');
    });
  });
} else {
  const SSLKeyWww = fs.readFileSync(
    join(__dirname, '..', 'ssl/www.chuntianxiaozhu.com.key'),
  );
  const SSLCertWww = fs.readFileSync(
    join(__dirname, '..', 'ssl/www.chuntianxiaozhu.com_bundle.pem'),
  );
  const KeyCerts = {
    'www.chuntianxiaozhu.com': tls.createSecureContext({
      key: SSLKeyWww,
      cert: SSLCertWww,
    }),
    'design.chuntianxiaozhu.com': tls.createSecureContext({
      key: fs.readFileSync(
        join(__dirname, '..', 'ssl/design.chuntianxiaozhu.com.key'),
      ),
      cert: fs.readFileSync(
        join(__dirname, '..', 'ssl/design.chuntianxiaozhu.com_bundle.pem'),
      ),
    }),
    'develop.chuntianxiaozhu.com': tls.createSecureContext({
      key: fs.readFileSync(
        join(__dirname, '..', 'ssl/develop.chuntianxiaozhu.com.key'),
      ),
      cert: fs.readFileSync(
        join(__dirname, '..', 'ssl/develop.chuntianxiaozhu.com_bundle.pem'),
      ),
    }),
    'waiter.chuntianxiaozhu.com': tls.createSecureContext({
      key: fs.readFileSync(
        join(__dirname, '..', 'ssl/waiter.chuntianxiaozhu.com.key'),
      ),
      cert: fs.readFileSync(
        join(__dirname, '..', 'ssl/waiter.chuntianxiaozhu.com_bundle.pem'),
      ),
    }),
  };
  bootstrap().then(async ({ app, server }) => {
    await app.init();
    http.createServer(server).listen(80);
    https
      .createServer(
        {
          SNICallback: function (domain, cb) {
            if (KeyCerts[domain]) {
              if (cb) {
                cb(null, KeyCerts[domain]);
              } else {
                return KeyCerts[domain]; //兼容Node老版本
              }
            } else {
              //一定要设置默认值，这样访问www.chuntianxiaozhu.com时，也可以访问，只是会有安全性提示
              if (cb) {
                cb(null, KeyCerts['www.chuntianxiaozhu.com']);
              } else {
                return KeyCerts['www.chuntianxiaozhu.com'];
              }
            }
          },
          key: SSLKeyWww,
          cert: SSLCertWww,
          rejectUnauthorized: false,
        },
        server,
      )
      .listen(443);
    console.log('服务启动在80端口');
  });
}

export { bootstrap };
