// module dependencies
import _ from 'lodash';
import path from 'path';
import Utils from '../utils';

/**
 * Manager for server instances.
 */
class Servers {

  /**
   * Engine API instance.
   * @type {null}
   */
  api = null;

  /**
   * Array with all running server instances.
   *
   * @type {{}}
   */
  servers = {};

  /**
   * Class constructor.
   *
   * @param api engine api instance.
   */
  constructor(api) {
    this.api = api;
  }

  loadServers(next) {
    let self = this;

    // get list with the server files
    let serversFiles = Utils.getFiles(path.resolve(__dirname + '/../servers'));

    let started = 0;

    // iterate all server files
    _.forEach(serversFiles, function (file) {
      let parts = file.split(/[\/\\]+/);
      let server = _.last(parts).split('.')[ 0 ];

      // only load `.js` files (in debug we also have `.map`files)
      if (_.last(_.last(parts).split('.')) !== 'js') {
        return;
      }

      // check if the server is enabled on app config
      if (self.api.config.servers[ server ] && self.api.config.servers[ server ].enable == true) {
        // save the server instance
        self.servers[ server ] = new (require(file).default)(self.api, self.api.config.servers[ server ]);
        self.api.log(`initialized server: ${server}`, 'debug');
        started++;

        process.nextTick(function () {
          started--;
          if (started === 0) {
            next();
          }
        });
      }
    });

    if (started == 0) {
      next();
    }
  }

  startServers(next) {
    let started = 0;

    // check if exists any server loaded
    if (_.size(this.servers) === 0) {
      next();
    }

    for (let server in this.servers) {
      started++;

      this.api.log(`starting server: ${server}`, 'notice');
      this.servers[ server ].start(function (error) {
        if (error) {
          return next(error);
        }

        process.nextTick(function () {
          started--;
          if (started === 0) {
            next();
          }
        });
      });
    }
  }
}

export default class {

  /**
   * This should be loaded after all engine
   * loading initializers.
   *
   * @type {number}
   */
  static loadPriority = 30;

  static load(api, next) {
    // instance the server manager
    api.servers = new Servers(api);

    // load enabled servers
    api.servers.loadServers(next);
  }

  static start(api, next) {
    // start the serves
    api.servers.startServers(next);
  }

}

@@ -2060,16 +2060,1019 @@
    %7D%0A  %7D
+%0A%0A  stopServers(next) %7B%0A    let self = this;%0A    let started = 0;%0A%0A    // check if exists any started server%0A    if (self.servers.length === 0) %7B%0A      next();%0A    %7D%0A%0A    for (let server in self.servers) %7B%0A      started++;%0A%0A      ((server) =%3E %7B%0A        if (self.api.config.servers%5B server %5D && self.api.config.servers%5B server %5D.enabled === true %7C%7C !self.api.config.servers%5B server %5D) %7B%0A          self.api.log(%60stopping server: $%7Bserver%7D%60, 'notice');%0A          self.servers%5B server %5D.stop(function (err) %7B%0A            if (err) %7B%0A              return next(err);%0A            %7D%0A%0A            process.nextTick(() =%3E %7B%0A              self.api.log(%60server stopped: $%7Bserver%7D%60, 'debug');%0A              started--;%0A              if (started === 0) %7B%0A                next();%0A              %7D%0A            %7D);%0A          %7D);%0A        %7D else %7B%0A          process.nextTick(() =%3E %7B%0A            started--;%0A            if (started === 0) %7B%0A              next();%0A            %7D%0A          %7D);%0A        %7D%0A      %7D)(server);%0A    %7D%0A  %7D
 %0A%7D%0A%0Aexpo
@@ -3228,16 +3228,45 @@
  = 30;%0A%0A
+  static stopPriority = 10;%0A%0A
   static
@@ -3465,25 +3465,22 @@
 / start 
-the 
 serve
+r
 s%0A    ap
@@ -3514,10 +3514,97 @@
 );%0A  %7D%0A%0A
+  static stop(api, next) %7B%0A    // stop servers%0A    api.servers.stopServers(next);%0A  %7D%0A%0A
 %7D%0A

Add a stop action to the servers initializer