
/*
 * This file is part of the Konsserto package.
 *
 * (c) Jessym Reziga <jessym@konsserto.com>
 * (c) Marvin Frachet <marvin@konsserto.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
var CONFIG, ExceptionHandler, HttpRequestException, Kernel, ServiceContainer, Tools, cc, wait;

cc = use('cli-color');

wait = use('wait.for');

CONFIG = use('/app/config/config');

ExceptionHandler = use('@Konsserto/Component/Debug/ExceptionHandler');

HttpRequestException = use('@Konsserto/Component/HttpKernel/Exception/HttpRequestException');

ServiceContainer = use('@Konsserto/Component/DependencyInjection/ServiceContainer');

Tools = use('@Konsserto/Component/Static/Tools');

Kernel = (function() {
  Kernel.VERSION = '0.0.46';

  Kernel.VERSION_ID = 1;

  function Kernel(environment, debug, mode) {
    this.environment = environment != null ? environment : 'dev';
    this.debug = debug != null ? debug : true;
    this.mode = mode != null ? mode : 'app';
    global.NODE_ENV = this.environment;
    global.env = this.environment;
    this.booted = false;
  }

  Kernel.prototype.getEnvironment = function() {
    return this.environment;
  };

  Kernel.prototype.getDebug = function() {
    return this.debug;
  };

  Kernel.prototype.boot = function() {
    var bundle, name, _ref;
    this.checkMode();
    this.initContainer();
    _ref = this.container.get('Application').getBundles();
    for (name in _ref) {
      bundle = _ref[name];
      bundle.setContainer(this.container);
      bundle.boot();
    }
    return this.booted = true;
  };

  Kernel.prototype.shutdown = function(exitCode) {
    var bundle, name, _ref;
    if (exitCode == null) {
      exitCode = -1;
    }
    console.log('\n' + cc.white.bgRed('[Power OFF]') + ' Shutdown Konsserto');
    if (this.booted === false) {
      return;
    }
    this.booted = false;
    _ref = this.container.get('Application').getBundles();
    for (name in _ref) {
      bundle = _ref[name];
      bundle.shutdown();
      bundle.setContainer(void 0);
    }
    console.log('[Container] Shutdown Service Container\n');
    this.container = null;
    return process.exit(exitCode);
  };

  Kernel.prototype.isBooted = function() {
    return this.booted;
  };

  Kernel.prototype.initContainer = function() {
    this.container = new ServiceContainer(this);
    return this.requestStack = this.container.get('Request_Stack');
  };

  Kernel.prototype.checkMode = function() {
    if (this.mode === 'console') {
      return console.log = function() {};
    }
  };

  Kernel.prototype.handle = function(route) {
    var e;
    try {
      return this.handleRaw(route);
    } catch (_error) {
      e = _error;
      this.finishRequest(route.getRequest());
      throw e;
    }
  };

  Kernel.prototype.handleRaw = function(route) {
    var definition;
    this.requestStack.push(route.getRequest());
    definition = route.getDefinition();
    if (!route.methodExists()) {
      throw new Error('Method ' + route.getMethod() + ' doesn\'t exists in ' + definition.getControllerName());
    }
    if (definition.isAsynchronous()) {
      return route.getResponse();
    } else {
      return wait.launchFiber((function(_this) {
        return function() {
          return route.getResponse();
        };
      })(this));
    }
  };

  Kernel.prototype.finishRequest = function(req) {
    return this.requestStack.pop(req);
  };

  Kernel.prototype.start = function(port) {
    var KSc, app, domain;
    domain = require('domain').create();
    domain.on('error', (function(_this) {
      return function(err) {
        var engine, response;
        response = _this.container.get('Request_Stack').getCurrentRequest().res;
        engine = _this.container.get('Templating');
        return ExceptionHandler.handle(err, response, engine);
      };
    })(this));
    domain.run((function(_this) {
      return function() {
        return _this.boot();
      };
    })(this));
    KSc = cc.xterm(255).bgXterm(0);
    console.log(KSc('  _  __                             _        '));
    console.log(KSc(' | |/ /                            | |       '));
    console.log(KSc(' | \' / ___  _ __  ___ ___  ___ _ __| |_ ___  '));
    console.log(KSc(' |  < / _ \\| \'_ \\/ __/ __|/ _ \\ \'__| __/ _ \\ '));
    console.log(KSc(' | . \\ (_) | | | \\__ \\__ \\  __/ |  | || (_) |'));
    console.log(KSc(' |_|\\_\\___/|_| |_|___/___/\\___|_|  \\__ \\___/ '));
    console.log(KSc(''));
    return app = this.container.get('Application').start(port);
  };

  return Kernel;

})();

module.exports = Kernel;
