import Ember from 'ember';

export default function(app, prefix) {
  var regex = new RegExp('^' + prefix + '\/((?:instance-)?initializers)\/');
  var getKeys = (Object.keys || Ember.keys);
  var moduleNames = getKeys(requirejs._eak_seen);

  for (var i = 0; i < moduleNames.length; i++) {
    var moduleName = moduleNames[i];
    var matches = regex.exec(moduleName);

    if (matches && matches.length === 2) {
      var module = require(moduleName, null, null, true);
      if (!module) { throw new Error(moduleName + ' must export an initializer.'); }

      var initializerType = Ember.String.camelize(matches[1].substring(0, matches[1].length - 1));
      var initializer = module['default'];
      if (!initializer.name) {
        var initializerName = moduleName.match(/[^\/]+\/?$/)[0];
        initializer.name = initializerName;
      }

      if (app[initializerType]) {
        app[initializerType](initializer);
      }
    }
  }
}

function resolveInitializer(moduleName) {
  var module = require(moduleName, null, null, true);
  if (!module) {
    throw new Error(moduleName + ' must export an initializer.');
  }
  var initializer = module['default'];
  if (!initializer.name) {
    initializer.name = moduleName.slice(moduleName.lastIndexOf('/') + 1);
  }
  return initializer;
}

function registerInitializers(app, moduleNames) {
  for (var i = 0; i < moduleNames.length; i++) {
    app.initializer(resolveInitializer(moduleNames[i]));
  }
}

function registerInstanceInitializers(app, moduleNames) {
  for (var i = 0; i < moduleNames.length; i++) {
    app.instanceInitializer(resolveInitializer(moduleNames[i]));
  }
}

export default function (app, prefix) {
  var initializerPrefix =  prefix + '/initializers/';
  var instanceInitializerPrefix =  prefix + '/instance-initializers/';
  var initializers = [];
  var instanceInitializers = [];
  // this is 2 pass because generally the first pass is the problem
  // and is reduced, and resolveInitializer has potential to deopt
  var moduleNames = Object.keys(requirejs._eak_seen);
  for (var i = 0; i < moduleNames.length; i++) {
    var moduleName = moduleNames[i];
    if (moduleName.lastIndexOf(initializerPrefix, 0) === 0) {
      initializers.push(moduleName);
    } else if (moduleName.lastIndexOf(instanceInitializerPrefix, 0) === 0) {
      instanceInitializers.push(moduleName);
    }
  }
  registerInitializers(app, initializers);
  registerInstanceInitializers(app, instanceInitializers);
}

Fix deopt with regex matches field load optimizing to undefined.
Fix deopt with regex matches field load optimizing to undefined.

Looping over a large array is fast if you minimize the work done on the
loop. In the app I tested there were 3000+ modules, 23 initializers, and
13 instance initializers. It is best to save the require work that has a
higher chance to cause JIT issues.
