"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = _default;

function _react() {
  const data = _interopRequireDefault(require("react"));

  _react = function _react() {
    return data;
  };

  return data;
}

function _fs() {
  const data = require("fs");

  _fs = function _fs() {
    return data;
  };

  return data;
}

function _chalk() {
  const data = _interopRequireDefault(require("chalk"));

  _chalk = function _chalk() {
    return data;
  };

  return data;
}

function _umiNotify() {
  const data = _interopRequireDefault(require("umi-notify"));

  _umiNotify = function _umiNotify() {
    return data;
  };

  return data;
}

var _createRouteMiddleware = _interopRequireDefault(require("./createRouteMiddleware"));

var _watch = require("../../../getConfig/watch");

var _getRouteManager = _interopRequireDefault(require("../getRouteManager"));

var _getFilesGenerator = _interopRequireDefault(require("../getFilesGenerator"));

var _getPort = _interopRequireDefault(require("./getPort"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function _default(api) {
  const service = api.service,
        config = api.config,
        log = api.log,
        debug = api.debug,
        printUmiError = api.printUmiError,
        UmiError = api.UmiError;
  const cwd = service.cwd;
  let hasUIArg = false;
  api.addHTMLHeadScript(() => {
    return hasUIArg ? {
      content: (0, _fs().readFileSync)(require.resolve('./injectUI'), 'utf-8')
    } : [];
  });
  api.registerCommand('dev', {
    webpack: true,
    description: 'start a dev server for development'
  }, /*#__PURE__*/function () {
    var _ref = _asyncToGenerator(function* (args = {}) {
      _umiNotify().default.onDevStart({
        name: 'umi',
        version: 2
      });

      const RoutesManager = (0, _getRouteManager.default)(service);
      RoutesManager.fetchRoutes();
      const portFromArgs = args.port,
            ui = args.ui;

      if (ui) {
        hasUIArg = true;
      }

      const port = yield (0, _getPort.default)(portFromArgs);
      service.port = port;
      process.env.NODE_ENV = 'development';
      service.applyPlugins('onStart');
      return new Promise((resolve, reject) => {
        service._applyPluginsAsync('onStartAsync').then(() => {
          const filesGenerator = (0, _getFilesGenerator.default)(service, {
            RoutesManager,
            mountElementId: config.mountElementId
          });
          debug('generate files');
          filesGenerator.generate();
          let server = null; // Add more service methods.

          service.restart = why => {
            if (!server) {
              log.debug(`Server is not ready, ${_chalk().default.underline.cyan('api.restart')} does not work.`);
              return;
            }

            if (why) {
              log.pending(`Since ${_chalk().default.cyan.underline(why)}, try to restart server...`);
            } else {
              log.pending(`Try to restart server...`);
            }

            (0, _watch.unwatch)();
            filesGenerator.unwatch();
            server.close();
            process.send({
              type: 'RESTART'
            });
          };

          service.refreshBrowser = () => {
            if (!server) return;
            server.sockWrite(server.sockets, 'content-changed');
          };

          service.printError = messages => {
            if (!server) return;
            messages = typeof messages === 'string' ? [messages] : messages;
            server.sockWrite(server.sockets, 'errors', messages);
          };

          service.printWarn = messages => {
            if (!server) return;
            messages = typeof messages === 'string' ? [messages] : messages;
            server.sockWrite(server.sockets, 'warns', messages);
          };

          service.rebuildTmpFiles = () => {
            filesGenerator.rebuild();
          };

          service.rebuildHTML = () => {
            // Currently, refresh browser will get new HTML.
            service.applyPlugins('onHTMLRebuild');
            service.refreshBrowser();
          };

          function startWatch() {
            filesGenerator.watch();
            service.userConfig.setConfig(service.config);
            service.userConfig.watchWithDevServer();
          }

          service._applyPluginsAsync('_beforeDevServerAsync').then(() => {
            debug('start dev server with af-webpack/dev');
            const _service$config$histo = service.config.history,
                  history = _service$config$histo === void 0 ? 'browser' : _service$config$histo;

            require('af-webpack/dev').default({
              cwd,
              port,
              history: typeof history === 'string' ? history : history[0],
              base: service.config.base,
              webpackConfig: service.webpackConfig,
              proxy: service.config.proxy || {},
              contentBase: './path-do-not-exists',

              _beforeServerWithApp(app) {
                // @private
                service.applyPlugins('_beforeServerWithApp', {
                  args: {
                    app
                  }
                });
              },

              beforeMiddlewares: service.applyPlugins('addMiddlewareAhead', {
                initialValue: [...(service.ssrWebpackConfig ? [require('af-webpack/webpack-dev-middleware')(require('af-webpack/webpack')(service.ssrWebpackConfig), {})] : [])]
              }),
              afterMiddlewares: service.applyPlugins('addMiddleware', {
                initialValue: [...(process.env.ROUTE_MIDDLEWARE !== 'none' ? [(0, _createRouteMiddleware.default)(service)] : [])]
              }),

              beforeServer(devServer) {
                server = devServer;
                service.applyPlugins('beforeDevServer', {
                  args: {
                    server: devServer
                  }
                });
              },

              afterServer(devServer, devServerPort) {
                service.applyPlugins('afterDevServer', {
                  args: {
                    server: devServer,
                    devServerPort
                  }
                });
                startWatch();
              },

              onFail({
                stats
              }) {
                printUmiError(new UmiError({
                  context: {
                    stats
                  }
                }), {
                  detailsOnly: true
                });
              },

              onCompileDone({
                isFirstCompile,
                stats,
                port,
                urls
              }) {
                service.__chunks = stats.compilation.chunks;
                service.applyPlugins('onDevCompileDone', {
                  args: {
                    isFirstCompile,
                    stats,
                    port,
                    server,
                    urls
                  }
                });

                if (isFirstCompile) {
                  _umiNotify().default.onDevComplete({
                    name: 'umi',
                    version: 2
                  });

                  resolve({
                    port,
                    stats,
                    server
                  });
                }
              }

            });
          }).catch(e => {
            log.error(e);
          });
        }).catch(e => {
          log.error(e);
          process.exit(1);
        });
      });
    });

    return function () {
      return _ref.apply(this, arguments);
    };
  }());
}