const { join } = require('path');
const { writeFileSync, mkdirSync, existsSync } = require('fs');
const rimraf = require('rimraf');
const serveStatic = require('serve-static');
const { resolve } = require('path');
const { portfinder, chalk, delay } = require('@umijs/utils');
const argv = require('./argv');
const setup = require('./middlewares/frontendMiddleware');
const pkg = require('../package.json');
const config = require('../config/config');
const mockMiddewares = require('./mock');
const emitter = require('./event');
const Server = require('./server');
const loadDotEnv = require('./utils/loadDotEnv');
const { getSchema } = require('./openapi');
(async () => {
  const defaultPort =
    process.env.PORT ||
    argv.port ||
    (config && config.devServer && config.devServer.port);
  const port = await portfinder.getPortPromise({
    port: defaultPort ? parseInt(String(defaultPort), 10) : 8080,
  });
  const homename =
    process.env.HOST ||
    (config && config.devServer && config.devServer.host) ||
    '127.0.0.1';
  console.log(chalk.cyan('Starting the development server...'));
  // process.send && process.send({ type: 'UPDATE_PORT', port });
  const isHTTPS = process.env.HTTPS || (argv && argv.https);

  await delay(500);
  const absNodeModulesPath = `${process.cwd()}/node_modules`;
  const openAPIFilesPath = join(absNodeModulesPath, 'civ_open_api');

  const loadEnv = () => {
    const basePath = join(process.cwd(), '.env');
    const localPath = `${basePath}.local`;
    loadDotEnv(basePath);
    loadDotEnv(localPath);
  };

  loadEnv();

  // const absNodeModulesPath = cwd + '/node_modules';
  try {
    if (existsSync(openAPIFilesPath)) {
      rimraf.sync(openAPIFilesPath);
    }
    mkdirSync(join(openAPIFilesPath));
  } catch (error) {
    console.error(error);
  }

  const server = new Server({
    compress: true,
    https: !!isHTTPS,
    headers: {
      'access-control-allow-origin': '*',
    },
    port,
    beforeMiddlewares: [
      (config.mock || process.env.MOCK !== 'none') && mockMiddewares,
    ],
    afterMiddlewares: [serveStatic(openAPIFilesPath)],
    proxy: config.proxy,
    ...(config.devServer || {}),
  });


  setup(
    server.app,
    {
      outputPath: resolve(process.cwd(), pkg.name.toLocaleLowerCase()),
      publicPath: `/${pkg.name.toLocaleLowerCase()}`,
    },
    config,
    {
      port,
      homename,
    },
  );

  emitter.on('onDevCompileDone', async () => {
    try {
      const openAPIConfig = config.openAPI;
      if (openAPIConfig && openAPIConfig.schemaPath) {
        const openAPIJson = await getSchema(openAPIConfig.schemaPath);
        writeFileSync(
          join(openAPIFilesPath, 'civ-plugins_openapi.json'),
          JSON.stringify(openAPIJson, null, 2),
        );
      }
    } catch (error) {
      console.error(error);
    }
  });

  await server.listen({
    port,
    homename,
  });
})();
