'use strict';

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

var _regenerator;

function _load_regenerator() {
  return _regenerator = _interopRequireDefault(require('babel-runtime/regenerator'));
}

var _path;

function _load_path() {
  return _path = _interopRequireDefault(require('path'));
}

var _ramda;

function _load_ramda() {
  return _ramda = _interopRequireDefault(require('ramda'));
}

var _fsExtra;

function _load_fsExtra() {
  return _fsExtra = _interopRequireDefault(require('fs-extra'));
}

var _extension;

function _load_extension() {
  return _extension = _interopRequireDefault(require('./extension'));
}

var _consumer;

function _load_consumer() {
  return _consumer = require('../consumer');
}

var _logger;

function _load_logger() {
  return _logger = _interopRequireDefault(require('../logger/logger'));
}

var _constants;

function _load_constants() {
  return _constants = require('../constants');
}

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

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

/**
 * Load all extensions
 * Regular, core, globals
 */
exports.default = function () {
  var _ref = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee() {
    var consumer, consumerPath, scopePath, rawExtensions, globalBitJson, globalRawExtensions, extensions;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            _context.prev = 0;

            (_logger || _load_logger()).default.info('start loading extensions');
            _context.next = 4;
            return (0, (_consumer || _load_consumer()).loadConsumer)(null, false);

          case 4:
            consumer = _context.sent;
            consumerPath = null;
            scopePath = null;
            rawExtensions = {};

            if (consumer) {
              rawExtensions = consumer.bitJson.extensions || {};
              consumerPath = consumer.getPath();
              scopePath = consumer.scope.path;
            }

            // Load global extensions
            _context.next = 11;
            return _getGlobalBitJson(false);

          case 11:
            globalBitJson = _context.sent;
            globalRawExtensions = globalBitJson && globalBitJson.extensions;
            // Merge the global with the local extensions only if exists
            // The local extension is higher priority than the global ones since they are closer to the user
            // This mechanism is for internal use by bitsrc server and should not be used by the users

            if (globalRawExtensions) {
              rawExtensions = (_ramda || _load_ramda()).default.mergeDeepLeft(rawExtensions, globalRawExtensions);
            }
            extensions = (_ramda || _load_ramda()).default.values((_ramda || _load_ramda()).default.mapObjIndexed(_loadExtension(consumerPath, scopePath), rawExtensions));
            return _context.abrupt('return', Promise.all(extensions));

          case 18:
            _context.prev = 18;
            _context.t0 = _context['catch'](0);

            (_logger || _load_logger()).default.error('loading extensions failed');
            (_logger || _load_logger()).default.error(_context.t0);
            return _context.abrupt('return', []);

          case 23:
          case 'end':
            return _context.stop();
        }
      }
    }, _callee, this, [[0, 18]]);
  }));

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

  return loadExtensions;
}();

/**
 * Load specific extension
 * @param {string} consumerPath
 * @param {string} scopePath
 */


var _loadExtension = function _loadExtension(consumerPath, scopePath) {
  return function () {
    var rawConfig = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    var name = arguments[1];

    var loadArgs = {
      name,
      rawConfig: rawConfig.config,
      options: rawConfig.options,
      consumerPath,
      scopePath
    };
    return (_extension || _load_extension()).default.load(loadArgs);
  };
};

/**
 * Load the global bit.json file (in order to get the global extensions)
 * @param {boolean} throws - whether to throw an error if the file corrupted
 */
var _getGlobalBitJson = function () {
  var _ref2 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee2(throws) {
    var globalBitJsonPath, exists;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee2$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            globalBitJsonPath = (_path || _load_path()).default.join((_constants || _load_constants()).GLOBAL_CONFIG, (_constants || _load_constants()).BIT_JSON);
            _context2.next = 3;
            return (_fsExtra || _load_fsExtra()).default.pathExists(globalBitJsonPath);

          case 3:
            exists = _context2.sent;

            if (exists) {
              _context2.next = 6;
              break;
            }

            return _context2.abrupt('return', null);

          case 6:
            return _context2.abrupt('return', (_fsExtra || _load_fsExtra()).default.readJson(globalBitJsonPath, { throws })
            // Implementing the catch my self since the throws: false not really workging
            .catch(function (e) {
              if (throws) {
                throw e;
              }
              (_logger || _load_logger()).default.debug('error during loading global bit.json');
              (_logger || _load_logger()).default.debug(e);
              return null;
            }));

          case 7:
          case 'end':
            return _context2.stop();
        }
      }
    }, _callee2, undefined);
  }));

  return function _getGlobalBitJson(_x2) {
    return _ref2.apply(this, arguments);
  };
}();