"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

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

function _bluebird() {
  const data = require("bluebird");

  _bluebird = function () {
    return data;
  };

  return data;
}

function _ramda() {
  const data = _interopRequireDefault(require("ramda"));

  _ramda = function () {
    return data;
  };

  return data;
}

function _logger() {
  const data = _interopRequireDefault(require("../logger/logger"));

  _logger = function () {
    return data;
  };

  return data;
}

function _utils() {
  const data = require("../utils");

  _utils = function () {
    return data;
  };

  return data;
}

function linkGenerator() {
  const data = _interopRequireWildcard(require("../links/link-generator"));

  linkGenerator = function () {
    return data;
  };

  return data;
}

function _nodeModulesLinker() {
  const data = _interopRequireDefault(require("./node-modules-linker"));

  _nodeModulesLinker = function () {
    return data;
  };

  return data;
}

function _componentDependencies() {
  const data = _interopRequireDefault(require("../scope/component-dependencies"));

  _componentDependencies = function () {
    return data;
  };

  return data;
}

function packageJsonUtils() {
  const data = _interopRequireWildcard(require("../consumer/component/package-json-utils"));

  packageJsonUtils = function () {
    return data;
  };

  return data;
}

function _generalError() {
  const data = _interopRequireDefault(require("../error/general-error"));

  _generalError = function () {
    return data;
  };

  return data;
}

function _componentMap() {
  const data = _interopRequireDefault(require("../consumer/bit-map/component-map"));

  _componentMap = function () {
    return data;
  };

  return data;
}

function _dataToPersist() {
  const data = _interopRequireDefault(require("../consumer/component/sources/data-to-persist"));

  _dataToPersist = function () {
    return data;
  };

  return data;
}

function _bitId() {
  const data = require("../bit-id");

  _bitId = function () {
    return data;
  };

  return data;
}

function _componentsList() {
  const data = _interopRequireDefault(require("../consumer/component/components-list"));

  _componentsList = function () {
    return data;
  };

  return data;
}

function _bitMap() {
  const data = _interopRequireDefault(require("../consumer/bit-map/bit-map"));

  _bitMap = function () {
    return data;
  };

  return data;
}

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

function _linkAllToNodeModules() {
  _linkAllToNodeModules = (0, _bluebird().coroutine)(function* (consumer) {
    const componentsIds = consumer.bitmapIds;
    if (_ramda().default.isEmpty(componentsIds)) throw new (_generalError().default)('nothing to link');
    const {
      components
    } = yield consumer.loadComponents(componentsIds);
    const nodeModuleLinker = new (_nodeModulesLinker().default)(components, consumer, consumer.bitMap);
    return nodeModuleLinker.link();
  });
  return _linkAllToNodeModules.apply(this, arguments);
}

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

function _getLinksInDistToWrite() {
  _getLinksInDistToWrite = (0, _bluebird().coroutine)(function* (component, componentMap, consumer, bitMap, componentWithDependencies) {
    if (!componentWithDependencies && !consumer) {
      throw new Error('getLinksInDistToWrite expects either consumer or componentWithDependencies to be defined');
    }

    const componentWithDeps = // $FlowFixMe
    componentWithDependencies || (yield component.toComponentWithDependencies(consumer));
    const componentsDependenciesLinks = linkGenerator().getComponentsDependenciesLinks([componentWithDeps], consumer, false, bitMap);
    const newMainFile = (0, _utils().pathNormalizeToLinux)(component.dists.calculateMainDistFile(component.mainFile));
    const rootDir = componentMap.rootDir;

    if (!rootDir) {
      throw new (_generalError().default)('getLinksInDistToWrite should get called on imported components only');
    }

    const nodeModuleLinker = new (_nodeModulesLinker().default)([component], consumer, bitMap);
    const nodeModuleLinks = yield nodeModuleLinker.getLinks();
    const dataToPersist = new (_dataToPersist().default)();
    dataToPersist.merge(nodeModuleLinks);
    dataToPersist.merge(componentsDependenciesLinks);
    const packageJsonFile = component.packageJsonFile;

    if (packageJsonFile) {
      packageJsonFile.addOrUpdateProperty('main', newMainFile);
      dataToPersist.addFile(packageJsonFile.toVinylFile());
    }

    const entryPoints = linkGenerator().getEntryPointsForComponent(component, consumer, bitMap);
    dataToPersist.addManyFiles(entryPoints);
    return dataToPersist;
  });
  return _getLinksInDistToWrite.apply(this, arguments);
}

function getReLinkDirectlyImportedDependenciesLinks(_x7, _x8) {
  return _getReLinkDirectlyImportedDependenciesLinks.apply(this, arguments);
}

function _getReLinkDirectlyImportedDependenciesLinks() {
  _getReLinkDirectlyImportedDependenciesLinks = (0, _bluebird().coroutine)(function* (components, consumer) {
    _logger().default.debug(`reLinkDirectlyImportedDependencies: found ${components.length} components to re-link`);

    const componentsWithDependencies = yield Promise.all(components.map(component => component.toComponentWithDependencies(consumer)));
    const componentsDependenciesLinks = linkGenerator().getComponentsDependenciesLinks(componentsWithDependencies, consumer, false, consumer.bitMap);
    const nodeModuleLinker = new (_nodeModulesLinker().default)(components, consumer, consumer.bitMap);
    const nodeModuleLinks = yield nodeModuleLinker.getLinks();
    const dataToPersist = new (_dataToPersist().default)();
    dataToPersist.merge(componentsDependenciesLinks);
    dataToPersist.merge(nodeModuleLinks);
    return dataToPersist;
  });
  return _getReLinkDirectlyImportedDependenciesLinks.apply(this, arguments);
}

function reLinkDependents(_x9, _x10) {
  return _reLinkDependents.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
 */


function _reLinkDependents() {
  _reLinkDependents = (0, _bluebird().coroutine)(function* (consumer, components) {
    const links = yield getReLinkDependentsData(consumer, components, new (_bitId().BitIds)());
    links.addBasePath(consumer.getPath());
    yield links.persistAllToFS();
  });
  return _reLinkDependents.apply(this, arguments);
}

function getReLinkDependentsData(_x11, _x12, _x13) {
  return _getReLinkDependentsData.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
 */


function _getReLinkDependentsData() {
  _getReLinkDependentsData = (0, _bluebird().coroutine)(function* (consumer, components, linkedComponents) {
    _logger().default.debug('linker: check whether there are direct dependents for re-linking');

    const directDependentComponents = yield consumer.getAuthoredAndImportedDependentsComponentsOf(components);
    const dataToPersist = new (_dataToPersist().default)();

    if (directDependentComponents.length) {
      if (directDependentComponents.every(c => linkedComponents.has(c.id))) {
        // all components already linked
        return dataToPersist;
      }

      const data = yield getReLinkDirectlyImportedDependenciesLinks(directDependentComponents, consumer);
      const packageJsonFiles = yield packageJsonUtils().changeDependenciesToRelativeSyntax(consumer, directDependentComponents, components);
      dataToPersist.merge(data);
      dataToPersist.addManyFiles(packageJsonFiles);
    }

    return dataToPersist;
  });
  return _getReLinkDependentsData.apply(this, arguments);
}

function getAllComponentsLinks(_x14) {
  return _getAllComponentsLinks.apply(this, arguments);
}

function _getAllComponentsLinks() {
  _getAllComponentsLinks = (0, _bluebird().coroutine)(function* ({
    componentsWithDependencies,
    writtenComponents,
    writtenDependencies,
    consumer,
    bitMap,
    createNpmLinkFiles
  }) {
    const dataToPersist = new (_dataToPersist().default)();
    const componentsDependenciesLinks = linkGenerator().getComponentsDependenciesLinks(componentsWithDependencies, consumer, createNpmLinkFiles, bitMap);

    if (writtenDependencies) {
      const uniqDependencies = _componentsList().default.getUniqueComponents(_ramda().default.flatten(writtenDependencies));

      const entryPoints = uniqDependencies.map(component => linkGenerator().getEntryPointsForComponent(component, consumer, bitMap));
      dataToPersist.addManyFiles(_ramda().default.flatten(entryPoints));
    }

    const entryPoints = writtenComponents.map(component => linkGenerator().getEntryPointsForComponent(component, consumer, bitMap));
    dataToPersist.addManyFiles(_ramda().default.flatten(entryPoints));
    const bitAngularEntryPoints = writtenComponents.map(component => linkGenerator().getEntryPointForAngularComponent(component, consumer, bitMap)).filter(x => x); // remove nulls when components are not Angular

    dataToPersist.addManyFiles(bitAngularEntryPoints);
    const allComponents = writtenDependencies ? [...writtenComponents, ..._ramda().default.flatten(writtenDependencies)] : writtenComponents;
    const nodeModuleLinker = new (_nodeModulesLinker().default)(allComponents, consumer, bitMap);
    const nodeModuleLinks = yield nodeModuleLinker.getLinks();
    dataToPersist.merge(nodeModuleLinks);

    if (consumer) {
      const allComponentsIds = _bitId().BitIds.uniqFromArray(allComponents.map(c => c.id));

      const reLinkDependentsData = yield getReLinkDependentsData(consumer, writtenComponents, allComponentsIds);
      dataToPersist.merge(reLinkDependentsData);
    }

    dataToPersist.merge(componentsDependenciesLinks);
    return dataToPersist;
  });
  return _getAllComponentsLinks.apply(this, arguments);
}