/*-----------------------------------------------------------------------------
| Copyright (c) Jupyter Development Team.
| Distributed under the terms of the Modified BSD License.
|----------------------------------------------------------------------------*/

require('es6-promise/auto');  // polyfill Promise on IE

import {
  PageConfig, URLExt
} from '@jupyterlab/coreutils';

__webpack_public_path__ = URLExt.join(
  PageConfig.getOption('baseUrl'),
  PageConfig.getOption('publicUrl')
);

// This needs to come after __webpack_public_path__ is set.
require('font-awesome/css/font-awesome.min.css');

/**
 * The main entry point for the application.
 */
function main() {
  var JupyterLab = require('@jupyterlab/application').JupyterLab;

  // Get the disabled extensions.
  var disabled = { patterns: [], matches: [] };
  var disabledExtensions = [];
  try {
    var tempDisabled = PageConfig.getOption('disabledExtensions');
    if (tempDisabled) {
      disabledExtensions = JSON.parse(tempDisabled).map(function(pattern) {
        disabled.patterns.push(pattern);
        return { raw: pattern, rule: new RegExp(pattern) };
      });
    }
  } catch (error) {
    console.warn('Unable to parse disabled extensions.', error);
  }

  // Get the deferred extensions.
  var deferred = { patterns: [], matches: [] };
  var deferredExtensions = [];
  var ignorePlugins = [];
  try {
    var tempDeferred = PageConfig.getOption('deferredExtensions');
    if (tempDeferred) {
      deferredExtensions = JSON.parse(tempDeferred).map(function(pattern) {
        deferred.patterns.push(pattern);
        return { raw: pattern, rule: new RegExp(pattern) };
      });
    }
  } catch (error) {
    console.warn('Unable to parse deferred extensions.', error);
  }

  function isDeferred(value) {
    return deferredExtensions.some(function(pattern) {
      return pattern.raw === value || pattern.rule.test(value);
    });
  }

  function isDisabled(value) {
    return disabledExtensions.some(function(pattern) {
      return pattern.raw === value || pattern.rule.test(value);
    });
  }

  var register = [];

  // Handle the registered mime extensions.
  var mimeExtensions = [];
  {{#each jupyterlab_mime_extensions}}
  try {
    if (isDeferred('{{key}}')) {
      deferred.matches.push('{{key}}');
      ignorePlugins.push('{{key}}');
    }
    if (isDisabled('{{@key}}')) {
      disabled.matches.push('{{@key}}');
    } else {
      var module = require('{{@key}}/{{this}}');
      var extension = module.default;

      // Handle CommonJS exports.
      if (!module.hasOwnProperty('__esModule')) {
        extension = module;
      }

      if (Array.isArray(extension)) {
        extension.forEach(function(plugin) {
          if (isDeferred(plugin.id)) {
            deferred.matches.push(plugin.id);
            ignorePlugins.push(plugin.id);
          }
          if (isDisabled(plugin.id)) {
            disabled.matches.push(plugin.id);
            return;
          }
          mimeExtensions.push(plugin);
        });
      } else {
        mimeExtensions.push(extension);
      }
    }
  } catch (e) {
    console.error(e);
  }
  {{/each}}

  // Handled the registered standard extensions.
  {{#each jupyterlab_extensions}}
  try {
    if (isDeferred('{{key}}')) {
      deferred.matches.push('{{key}}');
      ignorePlugins.push('{{key}}');
    }
    if (isDisabled('{{@key}}')) {
      disabled.matches.push('{{@key}}');
    } else {
      module = require('{{@key}}/{{this}}');
      extension = module.default;

      // Handle CommonJS exports.
      if (!module.hasOwnProperty('__esModule')) {
        extension = module;
      }

      if (Array.isArray(extension)) {
        extension.forEach(function(plugin) {
          if (isDeferred(plugin.id)) {
            deferred.matches.push(plugin.id);
            ignorePlugins.push(plugin.id);
          }
          if (isDisabled(plugin.id)) {
            disabled.matches.push(plugin.id);
            return;
          }
          register.push(plugin);
        });
      } else {
        register.push(extension);
      }
    }
  } catch (e) {
    console.error(e);
  }
  {{/each}}

  var lab = new JupyterLab({
    mimeExtensions: mimeExtensions,
    disabled: disabled,
    deferred: deferred
  });
  register.forEach(function(item) { lab.registerPluginModule(item); });
  lab.start({ ignorePlugins: ignorePlugins });

  // Expose global lab instance when in dev mode.
  if ((PageConfig.getOption('devMode') || '').toLowerCase() === 'true') {
    window.lab = lab;
  }

  // Handle a browser test.
  var browserTest = PageConfig.getOption('browserTest');
  if (browserTest.toLowerCase() === 'true') {
    var el = document.createElement('div');
    el.id = 'browserTest';
    document.body.appendChild(el);
    el.textContent = '[]';
    el.style.display = 'none';
    var errors = [];
    var reported = false;
    var timeout = 25000;

    var report = function(errors) {
      if (reported) {
        return;
      }
      reported = true;
      el.className = 'completed';
    }

    window.onerror = function(msg, url, line, col, error) {
      errors.push(String(error));
      el.textContent = JSON.stringify(errors)
    };
    console.error = function(message) {
      errors.push(String(message));
      el.textContent = JSON.stringify(errors)
    };

    lab.restored
      .then(function() { report(errors); })
      .catch(function(reason) { report([`RestoreError: ${reason.message}`]); });

    // Handle failures to restore after the timeout has elapsed.
    window.setTimeout(function() { report(errors); }, timeout);
  }

}

window.addEventListener('load', main);
