'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.linkComponents = exports.reLinkDependents = exports.writeLinksInDist = exports.linkAllToNodeModules = undefined;

var _regenerator;

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

var linkAllToNodeModules = exports.linkAllToNodeModules = function () {
  var _ref = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee(consumer) {
    var componentsIds, _ref2, components;

    return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            componentsIds = consumer.bitmapIds;

            if (!(_ramda || _load_ramda()).default.isEmpty(componentsIds)) {
              _context.next = 3;
              break;
            }

            throw new (_generalError || _load_generalError()).default('nothing to link');

          case 3:
            _context.next = 5;
            return consumer.loadComponents(componentsIds);

          case 5:
            _ref2 = _context.sent;
            components = _ref2.components;
            return _context.abrupt('return', (0, (_nodeModulesLinker || _load_nodeModulesLinker()).default)(components, consumer));

          case 8:
          case 'end':
            return _context.stop();
        }
      }
    }, _callee, this);
  }));

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

var writeLinksInDist = exports.writeLinksInDist = function () {
  var _ref3 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee2(component, componentMap, consumer) {
    var componentWithDeps, newMainFile;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee2$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            _context2.next = 2;
            return component.toComponentWithDependencies(consumer);

          case 2:
            componentWithDeps = _context2.sent;
            _context2.next = 5;
            return (_linkGenerator || _load_linkGenerator()).writeComponentsDependenciesLinks([componentWithDeps], consumer, false);

          case 5:
            newMainFile = (0, (_utils || _load_utils()).pathNormalizeToLinux)(component.dists.calculateMainDistFile(component.mainFile));

            if (componentMap.rootDir) {
              _context2.next = 8;
              break;
            }

            throw new (_generalError || _load_generalError()).default('writeLinksInDist should get called on imported components only');

          case 8:
            _context2.next = 10;
            return (_packageJson || _load_packageJson()).updateAttribute(consumer, componentMap.rootDir, 'main', newMainFile);

          case 10:
            _context2.next = 12;
            return (0, (_nodeModulesLinker || _load_nodeModulesLinker()).default)([component], consumer);

          case 12:
            return _context2.abrupt('return', (_linkGenerator || _load_linkGenerator()).writeEntryPointsForComponent(component, consumer));

          case 13:
          case 'end':
            return _context2.stop();
        }
      }
    }, _callee2, this);
  }));

  return function writeLinksInDist(_x2, _x3, _x4) {
    return _ref3.apply(this, arguments);
  };
}();

var reLinkDirectlyImportedDependencies = function () {
  var _ref4 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee3(components, consumer) {
    var componentsWithDependencies;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee3$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            (_logger || _load_logger()).default.debug(`reLinkDirectlyImportedDependencies: found ${components.length} components to re-link`);
            _context3.next = 3;
            return Promise.all(components.map(function (component) {
              return component.toComponentWithDependencies(consumer);
            }));

          case 3:
            componentsWithDependencies = _context3.sent;
            _context3.next = 6;
            return (_linkGenerator || _load_linkGenerator()).writeComponentsDependenciesLinks(componentsWithDependencies, consumer, false);

          case 6:
            _context3.next = 8;
            return (0, (_nodeModulesLinker || _load_nodeModulesLinker()).default)(components, consumer);

          case 8:
          case 'end':
            return _context3.stop();
        }
      }
    }, _callee3, this);
  }));

  return function reLinkDirectlyImportedDependencies(_x5, _x6) {
    return _ref4.apply(this, arguments);
  };
}();

/**
 * needed for the following cases:
 * 1) user is importing a component directly which was a dependency before. (before: IMPORTED, now: NESTED).
 * 2) user used bit-move to move a dependency to another directory.
 * as a result of the cases above, the link from the dependent to the dependency is broken.
 * find the dependents components and re-link them
 */


var reLinkDependents = exports.reLinkDependents = function () {
  var _ref5 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee4(consumer, components) {
    var directDependentComponents;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee4$(_context4) {
      while (1) {
        switch (_context4.prev = _context4.next) {
          case 0:
            (_logger || _load_logger()).default.debug('linker: check whether there are direct dependents for re-linking');
            _context4.next = 3;
            return findDirectDependentComponents(components, consumer);

          case 3:
            directDependentComponents = _context4.sent;

            if (!directDependentComponents.length) {
              _context4.next = 9;
              break;
            }

            _context4.next = 7;
            return reLinkDirectlyImportedDependencies(directDependentComponents, consumer);

          case 7:
            _context4.next = 9;
            return (_packageJson || _load_packageJson()).changeDependenciesToRelativeSyntax(consumer, directDependentComponents, components);

          case 9:
          case 'end':
            return _context4.stop();
        }
      }
    }, _callee4, this);
  }));

  return function reLinkDependents(_x7, _x8) {
    return _ref5.apply(this, arguments);
  };
}();

/**
 * link the components after import.
 * this process contains the following steps:
 * 1) writing link files to connect imported components to their dependencies
 * 2) writing index.js files (entry-point files) in the root directories of each one of the imported and dependencies components.
 * unless writePackageJson is true, because if package.json is written, its "main" attribute points to the entry-point.
 * 3) creating symlinks from components directories to node_modules
 * 4) in case a component was nested and now imported directly, re-link its dependents
 */


var linkComponents = exports.linkComponents = function () {
  var _ref6 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee5(componentsWithDependencies, writtenComponents, writtenDependencies, consumer, createNpmLinkFiles, writePackageJson) {
    var allComponents;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee5$(_context5) {
      while (1) {
        switch (_context5.prev = _context5.next) {
          case 0:
            allComponents = writtenDependencies ? [].concat(_toConsumableArray(writtenComponents), _toConsumableArray((_ramda || _load_ramda()).default.flatten(writtenDependencies))) : writtenComponents;
            _context5.next = 3;
            return (_linkGenerator || _load_linkGenerator()).writeComponentsDependenciesLinks(componentsWithDependencies, consumer, createNpmLinkFiles);

          case 3:
            if (!writtenDependencies) {
              _context5.next = 6;
              break;
            }

            _context5.next = 6;
            return Promise.all((_ramda || _load_ramda()).default.flatten(writtenDependencies).map(function (component) {
              return (_linkGenerator || _load_linkGenerator()).writeEntryPointsForComponent(component, consumer);
            }));

          case 6:
            if (writePackageJson) {
              _context5.next = 9;
              break;
            }

            _context5.next = 9;
            return Promise.all(writtenComponents.map(function (component) {
              return (_linkGenerator || _load_linkGenerator()).writeEntryPointsForComponent(component, consumer);
            }));

          case 9:
            _context5.next = 11;
            return (0, (_nodeModulesLinker || _load_nodeModulesLinker()).default)(allComponents, consumer);

          case 11:
            _context5.next = 13;
            return reLinkDependents(consumer, writtenComponents);

          case 13:
            return _context5.abrupt('return', allComponents);

          case 14:
          case 'end':
            return _context5.stop();
        }
      }
    }, _callee5, this);
  }));

  return function linkComponents(_x9, _x10, _x11, _x12, _x13, _x14) {
    return _ref6.apply(this, arguments);
  };
}();

var _ramda;

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

var _component;

function _load_component() {
  return _component = _interopRequireDefault(require('../consumer/component'));
}

var _constants;

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

var _logger;

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

var _utils;

function _load_utils() {
  return _utils = require('../utils');
}

var _linkGenerator;

function _load_linkGenerator() {
  return _linkGenerator = _interopRequireWildcard(require('../links/link-generator'));
}

var _nodeModulesLinker;

function _load_nodeModulesLinker() {
  return _nodeModulesLinker = _interopRequireDefault(require('./node-modules-linker'));
}

var _consumer;

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

var _componentDependencies;

function _load_componentDependencies() {
  return _componentDependencies = _interopRequireDefault(require('../scope/component-dependencies'));
}

var _packageJson;

function _load_packageJson() {
  return _packageJson = _interopRequireWildcard(require('../consumer/component/package-json'));
}

var _generalError;

function _load_generalError() {
  return _generalError = _interopRequireDefault(require('../error/general-error'));
}

var _componentMap;

function _load_componentMap() {
  return _componentMap = _interopRequireDefault(require('../consumer/bit-map/component-map'));
}

var _bitId;

function _load_bitId() {
  return _bitId = require('../bit-id');
}

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

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

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

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"); }); }; }

function findDirectDependentComponents(potentialDependencies, consumer) {
  var fsComponents = consumer.bitMap.getAllBitIds([(_constants || _load_constants()).COMPONENT_ORIGINS.IMPORTED, (_constants || _load_constants()).COMPONENT_ORIGINS.AUTHORED]);
  var potentialDependenciesIds = (_bitId || _load_bitId()).BitIds.fromArray(potentialDependencies.map(function (c) {
    return c.id;
  }));
  return consumer.scope.findDirectDependentComponents(fsComponents, potentialDependenciesIds);
}