'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getAllComponentsLinks = exports.getReLinkDependentsData = exports.reLinkDependents = exports.getLinksInDistToWrite = exports.linkAllToNodeModules = undefined;

var _regenerator;

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

var _bluebird;

function _load_bluebird() {
  return _bluebird = require('bluebird');
}

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

    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;
            nodeModuleLinker = new (_nodeModulesLinker || _load_nodeModulesLinker()).default(components, consumer, consumer.bitMap);
            return _context.abrupt('return', nodeModuleLinker.link());

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

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

var getLinksInDistToWrite = exports.getLinksInDistToWrite = function () {
  var _ref3 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee2(component, componentMap, consumer) {
    var componentWithDeps, componentsDependenciesLinks, newMainFile, rootDir, nodeModuleLinker, nodeModuleLinks, dataToPersist, packageJsonFile, entryPoints;
    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;
            componentsDependenciesLinks = (_linkGenerator || _load_linkGenerator()).getComponentsDependenciesLinks([componentWithDeps], consumer, false, consumer.bitMap);
            newMainFile = (0, (_utils || _load_utils()).pathNormalizeToLinux)(component.dists.calculateMainDistFile(component.mainFile));
            rootDir = componentMap.rootDir;

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

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

          case 8:
            nodeModuleLinker = new (_nodeModulesLinker || _load_nodeModulesLinker()).default([component], consumer, consumer.bitMap);
            _context2.next = 11;
            return nodeModuleLinker.getLinks();

          case 11:
            nodeModuleLinks = _context2.sent;
            dataToPersist = new (_dataToPersist || _load_dataToPersist()).default();

            dataToPersist.merge(nodeModuleLinks);
            dataToPersist.merge(componentsDependenciesLinks);
            _context2.next = 17;
            return (_packageJsonFile || _load_packageJsonFile()).default.load(rootDir);

          case 17:
            packageJsonFile = _context2.sent;

            if (packageJsonFile.fileExist) {
              packageJsonFile.addOrUpdateProperty('main', newMainFile);
              dataToPersist.addFile(packageJsonFile.toJSONFile());
            } else {
              // if package.json doesn't exist, we can't use its 'main' property to point to the entry point
              entryPoints = (_linkGenerator || _load_linkGenerator()).getEntryPointsForComponent(component, consumer);

              dataToPersist.addManyFiles(entryPoints);
            }
            return _context2.abrupt('return', dataToPersist);

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

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

var getReLinkDirectlyImportedDependenciesLinks = function () {
  var _ref4 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee3(components, consumer) {
    var componentsWithDependencies, componentsDependenciesLinks, nodeModuleLinker, nodeModuleLinks, dataToPersist;
    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;
            componentsDependenciesLinks = (_linkGenerator || _load_linkGenerator()).getComponentsDependenciesLinks(componentsWithDependencies, consumer, false, consumer.bitMap);
            nodeModuleLinker = new (_nodeModulesLinker || _load_nodeModulesLinker()).default(components, consumer, consumer.bitMap);
            _context3.next = 8;
            return nodeModuleLinker.getLinks();

          case 8:
            nodeModuleLinks = _context3.sent;
            dataToPersist = new (_dataToPersist || _load_dataToPersist()).default();

            dataToPersist.merge(componentsDependenciesLinks);
            dataToPersist.merge(nodeModuleLinks);
            return _context3.abrupt('return', dataToPersist);

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

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

var reLinkDependents = exports.reLinkDependents = function () {
  var _ref5 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee4(consumer, components) {
    var links;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee4$(_context4) {
      while (1) {
        switch (_context4.prev = _context4.next) {
          case 0:
            _context4.next = 2;
            return getReLinkDependentsData(consumer, components, new (_bitId || _load_bitId()).BitIds());

          case 2:
            links = _context4.sent;

            links.addBasePath(consumer.getPath());
            _context4.next = 6;
            return links.persistAllToFS();

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

  return function reLinkDependents(_x7, _x8) {
    return _ref5.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 getReLinkDependentsData = exports.getReLinkDependentsData = function () {
  var _ref6 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee5(consumer, components, linkedComponents) {
    var directDependentComponents, dataToPersist, data, packageJsonFiles;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee5$(_context5) {
      while (1) {
        switch (_context5.prev = _context5.next) {
          case 0:
            (_logger || _load_logger()).default.debug('linker: check whether there are direct dependents for re-linking');
            _context5.next = 3;
            return consumer.getAuthoredAndImportedDependentsComponentsOf(components);

          case 3:
            directDependentComponents = _context5.sent;
            dataToPersist = new (_dataToPersist || _load_dataToPersist()).default();

            if (!directDependentComponents.length) {
              _context5.next = 16;
              break;
            }

            if (!directDependentComponents.every(function (c) {
              return linkedComponents.has(c.id);
            })) {
              _context5.next = 8;
              break;
            }

            return _context5.abrupt('return', dataToPersist);

          case 8:
            _context5.next = 10;
            return getReLinkDirectlyImportedDependenciesLinks(directDependentComponents, consumer);

          case 10:
            data = _context5.sent;
            _context5.next = 13;
            return (_packageJsonUtils || _load_packageJsonUtils()).changeDependenciesToRelativeSyntax(consumer, directDependentComponents, components);

          case 13:
            packageJsonFiles = _context5.sent;

            dataToPersist.merge(data);
            dataToPersist.addManyFiles(packageJsonFiles);

          case 16:
            return _context5.abrupt('return', dataToPersist);

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

  return function getReLinkDependentsData(_x9, _x10, _x11) {
    return _ref6.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 getAllComponentsLinks = exports.getAllComponentsLinks = function () {
  var _ref7 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee6(_ref8) {
    var componentsWithDependencies = _ref8.componentsWithDependencies,
        writtenComponents = _ref8.writtenComponents,
        writtenDependencies = _ref8.writtenDependencies,
        consumer = _ref8.consumer,
        bitMap = _ref8.bitMap,
        createNpmLinkFiles = _ref8.createNpmLinkFiles,
        writePackageJson = _ref8.writePackageJson;

    var dataToPersist, componentsDependenciesLinks, uniqDependencies, entryPoints, _entryPoints, allComponents, nodeModuleLinker, nodeModuleLinks, allComponentsIds, reLinkDependentsData;

    return (_regenerator || _load_regenerator()).default.wrap(function _callee6$(_context6) {
      while (1) {
        switch (_context6.prev = _context6.next) {
          case 0:
            dataToPersist = new (_dataToPersist || _load_dataToPersist()).default();
            componentsDependenciesLinks = (_linkGenerator || _load_linkGenerator()).getComponentsDependenciesLinks(componentsWithDependencies, consumer, createNpmLinkFiles, bitMap);

            if (writtenDependencies) {
              uniqDependencies = (_componentsList || _load_componentsList()).default.getUniqueComponents((_ramda || _load_ramda()).default.flatten(writtenDependencies));
              entryPoints = uniqDependencies.map(function (component) {
                return (_linkGenerator || _load_linkGenerator()).getEntryPointsForComponent(component, consumer, bitMap);
              });

              dataToPersist.addManyFiles((_ramda || _load_ramda()).default.flatten(entryPoints));
            }
            if (!writePackageJson) {
              // no need for entry-point file if package.json is written.
              _entryPoints = writtenComponents.map(function (component) {
                return (_linkGenerator || _load_linkGenerator()).getEntryPointsForComponent(component, consumer, bitMap);
              });

              dataToPersist.addManyFiles((_ramda || _load_ramda()).default.flatten(_entryPoints));
            }
            allComponents = writtenDependencies ? [].concat(_toConsumableArray(writtenComponents), _toConsumableArray((_ramda || _load_ramda()).default.flatten(writtenDependencies))) : writtenComponents;
            nodeModuleLinker = new (_nodeModulesLinker || _load_nodeModulesLinker()).default(allComponents, consumer, bitMap);
            _context6.next = 8;
            return nodeModuleLinker.getLinks();

          case 8:
            nodeModuleLinks = _context6.sent;

            dataToPersist.merge(nodeModuleLinks);

            if (!consumer) {
              _context6.next = 16;
              break;
            }

            allComponentsIds = (_bitId || _load_bitId()).BitIds.uniqFromArray(allComponents.map(function (c) {
              return c.id;
            }));
            _context6.next = 14;
            return getReLinkDependentsData(consumer, writtenComponents, allComponentsIds);

          case 14:
            reLinkDependentsData = _context6.sent;

            dataToPersist.merge(reLinkDependentsData);

          case 16:

            dataToPersist.merge(componentsDependenciesLinks);
            return _context6.abrupt('return', dataToPersist);

          case 18:
          case 'end':
            return _context6.stop();
        }
      }
    }, _callee6, this);
  }));

  return function getAllComponentsLinks(_x12) {
    return _ref7.apply(this, arguments);
  };
}();

var _ramda;

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

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 _componentDependencies;

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

var _packageJsonUtils;

function _load_packageJsonUtils() {
  return _packageJsonUtils = _interopRequireWildcard(require('../consumer/component/package-json-utils'));
}

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 _dataToPersist;

function _load_dataToPersist() {
  return _dataToPersist = _interopRequireDefault(require('../consumer/component/sources/data-to-persist'));
}

var _bitId;

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

var _componentsList;

function _load_componentsList() {
  return _componentsList = _interopRequireDefault(require('../consumer/component/components-list'));
}

var _bitMap;

function _load_bitMap() {
  return _bitMap = _interopRequireDefault(require('../consumer/bit-map/bit-map'));
}

var _packageJsonFile;

function _load_packageJsonFile() {
  return _packageJsonFile = _interopRequireDefault(require('../consumer/component/package-json-file'));
}

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