'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.removeComponentsFromWorkspacesAndDependencies = exports.addWorkspacesToPackageJson = exports.updateAttribute = exports.addComponentsWithVersionToRoot = exports.write = exports.changeDependenciesToRelativeSyntax = exports.removeComponentsFromNodeModules = exports.addComponentsToRoot = undefined;

var _regenerator;

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

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

/**
 * Add components as dependencies to root package.json
 */
var addComponentsToRoot = function () {
  var _ref = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee(consumer, componentsIds) {
    var importedComponents, driver, PackageJson, componentsToAdd, registryPrefix;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            importedComponents = componentsIds.filter(function (id) {
              var componentMap = consumer.bitMap.getComponent(id);
              return componentMap.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.IMPORTED;
            });

            if (!(!importedComponents || !importedComponents.length)) {
              _context.next = 3;
              break;
            }

            return _context.abrupt('return');

          case 3:
            _context.next = 5;
            return consumer.driver.getDriver(false);

          case 5:
            driver = _context.sent;
            PackageJson = driver.PackageJson;
            componentsToAdd = (_ramda || _load_ramda()).default.fromPairs(importedComponents.map(function (componentId) {
              var componentMap = consumer.bitMap.getComponent(componentId);
              if (!componentMap.rootDir) {
                throw new (_generalError || _load_generalError()).default(`rootDir is missing from an imported component ${componentId.toString()}`);
              }
              var locationAsUnixFormat = convertToValidPathForPackageManager(componentMap.rootDir);
              return [componentId.toStringWithoutVersion(), locationAsUnixFormat];
            }));
            registryPrefix = getRegistryPrefix();
            _context.next = 11;
            return PackageJson.addComponentsIntoExistingPackageJson(consumer.getPath(), componentsToAdd, registryPrefix);

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

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

/**
 * Add given components with their versions to root package.json
 */


var addComponentsWithVersionToRoot = function () {
  var _ref2 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee2(consumer, componentsIds) {
    var driver, PackageJson, componentsToAdd;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee2$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            _context2.next = 2;
            return consumer.driver.getDriver(false);

          case 2:
            driver = _context2.sent;
            PackageJson = driver.PackageJson;
            componentsToAdd = (_ramda || _load_ramda()).default.fromPairs(componentsIds.map(function (id) {
              return [id.toStringWithoutVersion(), id.version];
            }));
            _context2.next = 7;
            return PackageJson.addComponentsIntoExistingPackageJson(consumer.getPath(), componentsToAdd, getRegistryPrefix());

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

  return function addComponentsWithVersionToRoot(_x3, _x4) {
    return _ref2.apply(this, arguments);
  };
}();

var getPackageDependency = function () {
  var _ref3 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee3(consumer, dependencyId, parentId) {
    var parentComponentMap, dependencyComponentMap;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee3$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            parentComponentMap = consumer.bitMap.getComponent(parentId);
            dependencyComponentMap = consumer.bitMap.getComponentIfExist(dependencyId);
            return _context3.abrupt('return', getPackageDependencyValue(dependencyId, parentComponentMap, dependencyComponentMap));

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

  return function getPackageDependency(_x5, _x6, _x7) {
    return _ref3.apply(this, arguments);
  };
}();

var changeDependenciesToRelativeSyntax = function () {
  var _ref4 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee5(consumer, components, dependencies) {
    var _this = this;

    var dependenciesIds, driver, PackageJson, updateComponent;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee5$(_context5) {
      while (1) {
        switch (_context5.prev = _context5.next) {
          case 0:
            dependenciesIds = (_bitId || _load_bitId()).BitIds.fromArray(dependencies.map(function (dependency) {
              return dependency.id;
            }));
            _context5.next = 3;
            return consumer.driver.getDriver(false);

          case 3:
            driver = _context5.sent;
            PackageJson = driver.PackageJson;

            updateComponent = function () {
              var _ref5 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee4(component) {
                var componentMap, packageJson, getPackages, devDeps, compilerDeps, testerDeps;
                return (_regenerator || _load_regenerator()).default.wrap(function _callee4$(_context4) {
                  while (1) {
                    switch (_context4.prev = _context4.next) {
                      case 0:
                        componentMap = consumer.bitMap.getComponent(component.id);
                        packageJson = void 0;
                        _context4.prev = 2;
                        _context4.next = 5;
                        return PackageJson.load(componentMap.rootDir);

                      case 5:
                        packageJson = _context4.sent;
                        _context4.next = 11;
                        break;

                      case 8:
                        _context4.prev = 8;
                        _context4.t0 = _context4['catch'](2);
                        return _context4.abrupt('return', Promise.resolve());

                      case 11:
                        getPackages = function getPackages(deps) {
                          var packages = deps.get().map(function (dependency) {
                            var dependencyId = dependency.id.toStringWithoutVersion();
                            if (dependenciesIds.searchWithoutVersion(dependency.id)) {
                              var dependencyComponent = dependencies.find(function (d) {
                                return d.id.isEqualWithoutVersion(dependency.id);
                              });
                              // $FlowFixMe dependencyComponent must be found (two line earlier there is a check for that)
                              var dependencyComponentMap = consumer.bitMap.getComponentIfExist(dependencyComponent.id);
                              var dependencyPackageValue = getPackageDependencyValue(dependencyId, componentMap, dependencyComponentMap);
                              return dependencyPackageValue ? [dependencyId, dependencyPackageValue] : [];
                            }
                            return [];
                          });
                          return (_ramda || _load_ramda()).default.fromPairs(packages);
                        };

                        devDeps = getPackages(component.devDependencies);
                        compilerDeps = getPackages(component.compilerDependencies);
                        testerDeps = getPackages(component.testerDependencies);

                        packageJson.addDependencies(getPackages(component.dependencies), getRegistryPrefix());
                        packageJson.addDevDependencies(_extends({}, devDeps, compilerDeps, testerDeps), getRegistryPrefix());
                        return _context4.abrupt('return', packageJson.write({ override: true }));

                      case 18:
                      case 'end':
                        return _context4.stop();
                    }
                  }
                }, _callee4, _this, [[2, 8]]);
              }));

              return function updateComponent(_x11) {
                return _ref5.apply(this, arguments);
              };
            }();

            return _context5.abrupt('return', Promise.all(components.map(function (component) {
              return updateComponent(component);
            })));

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

  return function changeDependenciesToRelativeSyntax(_x8, _x9, _x10) {
    return _ref4.apply(this, arguments);
  };
}();

var write = function () {
  var _ref6 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee8(consumer, component, bitDir) {
    var override = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;

    var _this2 = this;

    var writeBitDependencies = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
    var excludeRegistryPrefix = arguments[5];
    var PackageJson, getBitDependencies, bitDependencies, bitDevDependencies, bitCompilerDependencies, bitTesterDependencies, registryPrefix, name, getPackageJsonInstance, packageJson, distRootDir, distPackageJson;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee8$(_context8) {
      while (1) {
        switch (_context8.prev = _context8.next) {
          case 0:
            (_logger || _load_logger()).default.debug(`package-json.write. bitDir ${bitDir}. override ${override.toString()}`);
            PackageJson = consumer.driver.getDriver(false).PackageJson;

            getBitDependencies = function () {
              var _ref7 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee7(dependencies) {
                var dependenciesPackages;
                return (_regenerator || _load_regenerator()).default.wrap(function _callee7$(_context7) {
                  while (1) {
                    switch (_context7.prev = _context7.next) {
                      case 0:
                        if (writeBitDependencies) {
                          _context7.next = 2;
                          break;
                        }

                        return _context7.abrupt('return', {});

                      case 2:
                        dependenciesPackages = dependencies.get().map(function () {
                          var _ref8 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee6(dep) {
                            var packageDependency;
                            return (_regenerator || _load_regenerator()).default.wrap(function _callee6$(_context6) {
                              while (1) {
                                switch (_context6.prev = _context6.next) {
                                  case 0:
                                    _context6.next = 2;
                                    return getPackageDependency(consumer, dep.id, component.id);

                                  case 2:
                                    packageDependency = _context6.sent;
                                    return _context6.abrupt('return', [dep.id.toStringWithoutVersion(), packageDependency]);

                                  case 4:
                                  case 'end':
                                    return _context6.stop();
                                }
                              }
                            }, _callee6, _this2);
                          }));

                          return function (_x19) {
                            return _ref8.apply(this, arguments);
                          };
                        }());
                        _context7.t0 = (_ramda || _load_ramda()).default;
                        _context7.next = 6;
                        return Promise.all(dependenciesPackages);

                      case 6:
                        _context7.t1 = _context7.sent;
                        return _context7.abrupt('return', _context7.t0.fromPairs.call(_context7.t0, _context7.t1));

                      case 8:
                      case 'end':
                        return _context7.stop();
                    }
                  }
                }, _callee7, _this2);
              }));

              return function getBitDependencies(_x18) {
                return _ref7.apply(this, arguments);
              };
            }();

            _context8.next = 5;
            return getBitDependencies(component.dependencies);

          case 5:
            bitDependencies = _context8.sent;
            _context8.next = 8;
            return getBitDependencies(component.devDependencies);

          case 8:
            bitDevDependencies = _context8.sent;
            _context8.next = 11;
            return getBitDependencies(component.compilerDependencies);

          case 11:
            bitCompilerDependencies = _context8.sent;
            _context8.next = 14;
            return getBitDependencies(component.testerDependencies);

          case 14:
            bitTesterDependencies = _context8.sent;
            registryPrefix = getRegistryPrefix();
            name = excludeRegistryPrefix ? component.id.toStringWithoutVersion().replace(/\//g, '.') : convertIdToNpmName(component.id);

            getPackageJsonInstance = function getPackageJsonInstance(dir) {
              var packageJson = new PackageJson(dir, {
                name,
                version: component.version,
                homepage: component._getHomepage(),
                main: (0, (_path2 || _load_path2()).pathNormalizeToLinux)(component.dists.calculateMainDistFile(component.mainFile)),
                dependencies: component.packageDependencies,
                // Add environments PackageDependencies to the devDependencies in the package.json
                devDependencies: _extends({}, component.devPackageDependencies, component.compilerPackageDependencies, component.testerPackageDependencies),
                peerDependencies: component.peerPackageDependencies,
                componentRootFolder: dir,
                license: `SEE LICENSE IN ${!(_ramda || _load_ramda()).default.isEmpty(component.license) ? 'LICENSE' : 'UNLICENSED'}`
              });
              packageJson.addDependencies(bitDependencies, registryPrefix);
              packageJson.addDevDependencies(_extends({}, bitDevDependencies, bitCompilerDependencies, bitTesterDependencies), registryPrefix);
              return packageJson;
            };

            packageJson = getPackageJsonInstance(bitDir);

            if (!(!component.dists.isEmpty() && !component.dists.areDistsInsideComponentDir)) {
              _context8.next = 26;
              break;
            }

            distRootDir = component.dists.distsRootDir;

            if (distRootDir) {
              _context8.next = 23;
              break;
            }

            throw new (_generalError || _load_generalError()).default('component.dists.distsRootDir is not defined yet');

          case 23:
            distPackageJson = getPackageJsonInstance(distRootDir);
            _context8.next = 26;
            return distPackageJson.write({ override });

          case 26:
            _context8.next = 28;
            return packageJson.write({ override });

          case 28:
            return _context8.abrupt('return', packageJson);

          case 29:
          case 'end':
            return _context8.stop();
        }
      }
    }, _callee8, this);
  }));

  return function write(_x15, _x16, _x17) {
    return _ref6.apply(this, arguments);
  };
}();

var updateAttribute = function () {
  var _ref9 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee9(consumer, componentDir, attributeName, attributeValue) {
    var PackageJson, packageJson;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee9$(_context9) {
      while (1) {
        switch (_context9.prev = _context9.next) {
          case 0:
            PackageJson = consumer.driver.getDriver(false).PackageJson;
            _context9.prev = 1;
            _context9.next = 4;
            return PackageJson.load(componentDir);

          case 4:
            packageJson = _context9.sent;

            packageJson[attributeName] = attributeValue;
            return _context9.abrupt('return', packageJson.write({ override: true }));

          case 9:
            _context9.prev = 9;
            _context9.t0 = _context9['catch'](1);
            return _context9.abrupt('return', Promise.resolve());

          case 12:
          case 'end':
            return _context9.stop();
        }
      }
    }, _callee9, this, [[1, 9]]);
  }));

  return function updateAttribute(_x20, _x21, _x22, _x23) {
    return _ref9.apply(this, arguments);
  };
}();

/**
 * Adds workspace array to package.json - only if user wants to work with yarn workspaces
 */


var addWorkspacesToPackageJson = function () {
  var _ref10 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee10(consumer, customImportPath) {
    var rootDir, dependenciesDirectory, componentsDefaultDirectory, driver, PackageJson;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee10$(_context10) {
      while (1) {
        switch (_context10.prev = _context10.next) {
          case 0:
            if (!(consumer.bitJson.manageWorkspaces && consumer.bitJson.packageManager === 'yarn' && consumer.bitJson.useWorkspaces)) {
              _context10.next = 10;
              break;
            }

            rootDir = consumer.getPath();
            dependenciesDirectory = consumer.bitJson.dependenciesDirectory;
            componentsDefaultDirectory = consumer.dirStructure.componentsDefaultDirectory;
            _context10.next = 6;
            return consumer.driver.getDriver(false);

          case 6:
            driver = _context10.sent;
            PackageJson = driver.PackageJson;
            _context10.next = 10;
            return PackageJson.addWorkspacesToPackageJson(rootDir, componentsDefaultDirectory + (_constants || _load_constants()).SUB_DIRECTORIES_GLOB_PATTERN, dependenciesDirectory + (_constants || _load_constants()).SUB_DIRECTORIES_GLOB_PATTERN, customImportPath ? consumer.getPathRelativeToConsumer(customImportPath) : customImportPath);

          case 10:
          case 'end':
            return _context10.stop();
        }
      }
    }, _callee10, this);
  }));

  return function addWorkspacesToPackageJson(_x24, _x25) {
    return _ref10.apply(this, arguments);
  };
}();

var removeComponentsFromNodeModules = function () {
  var _ref11 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee11(consumer, componentIds) {
    var registryPrefix, pathsToRemove;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee11$(_context11) {
      while (1) {
        switch (_context11.prev = _context11.next) {
          case 0:
            (_logger || _load_logger()).default.debug(`removeComponentsFromNodeModules: ${componentIds.map(function (c) {
              return c.toString();
            }).join(', ')}`);
            registryPrefix = getRegistryPrefix();
            // paths without scope name, don't have a symlink in node-modules

            pathsToRemove = componentIds.map(function (id) {
              return id.scope ? (_consumer || _load_consumer()).default.getNodeModulesPathOfComponent(registryPrefix, id) : null;
            }).filter(function (a) {
              return a;
            }); // remove null

            (_logger || _load_logger()).default.debug(`deleting the following paths: ${pathsToRemove.join('\n')}`);
            // $FlowFixMe nulls were removed in the previous filter function
            return _context11.abrupt('return', Promise.all(pathsToRemove.map(function (componentPath) {
              return (_fsExtra || _load_fsExtra()).default.remove((_path || _load_path()).default.join(consumer.getPath(), componentPath));
            })));

          case 5:
          case 'end':
            return _context11.stop();
        }
      }
    }, _callee11, this);
  }));

  return function removeComponentsFromNodeModules(_x26, _x27) {
    return _ref11.apply(this, arguments);
  };
}();

var removeComponentsFromWorkspacesAndDependencies = function () {
  var _ref12 = _asyncToGenerator( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee12(consumer, rootDir, bitMap, componentIds) {
    var driver, PackageJson, dirsToRemove;
    return (_regenerator || _load_regenerator()).default.wrap(function _callee12$(_context12) {
      while (1) {
        switch (_context12.prev = _context12.next) {
          case 0:
            _context12.next = 2;
            return consumer.driver.getDriver(false);

          case 2:
            driver = _context12.sent;
            PackageJson = driver.PackageJson;

            if (!(consumer.bitJson.manageWorkspaces && consumer.bitJson.packageManager === 'yarn' && consumer.bitJson.useWorkspaces)) {
              _context12.next = 8;
              break;
            }

            dirsToRemove = componentIds.map(function (id) {
              return bitMap.getComponent(id, { ignoreVersion: true }).rootDir;
            });
            _context12.next = 8;
            return PackageJson.removeComponentsFromWorkspaces(rootDir, dirsToRemove);

          case 8:
            _context12.next = 10;
            return PackageJson.removeComponentsFromDependencies(rootDir, getRegistryPrefix(), componentIds.map(function (id) {
              return id.toStringWithoutVersion();
            }));

          case 10:
            _context12.next = 12;
            return removeComponentsFromNodeModules(consumer, componentIds);

          case 12:
          case 'end':
            return _context12.stop();
        }
      }
    }, _callee12, this);
  }));

  return function removeComponentsFromWorkspacesAndDependencies(_x28, _x29, _x30, _x31) {
    return _ref12.apply(this, arguments);
  };
}();

var _ramda;

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

var _path;

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

var _fsExtra;

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

var _bitId;

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

var _component;

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

var _constants;

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

var _componentMap;

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

var _utils;

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

var _globalConfig;

function _load_globalConfig() {
  return _globalConfig = require('../../api/consumer/lib/global-config');
}

var _consumer;

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

var _dependencies;

function _load_dependencies() {
  return _dependencies = require('./dependencies');
}

var _path2;

function _load_path2() {
  return _path2 = require('../../utils/path');
}

var _logger;

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

var _generalError;

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

var _bitMap;

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

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

function convertToValidPathForPackageManager(pathStr) {
  var prefix = 'file:'; // it works for both, Yarn and NPM
  return prefix + (pathStr.startsWith('.') ? pathStr : `./${pathStr}`);
}

/**
 * Only imported components should be saved with relative path in package.json
 * If a component is nested or imported as a package dependency, it should be saved with the version
 * If a component is authored, no need to save it as a dependency of the imported component because
 * the root package.json takes care of it already.
 */
function getPackageDependencyValue(dependencyId, parentComponentMap, dependencyComponentMap) {
  if (!dependencyComponentMap || dependencyComponentMap.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.NESTED) {
    return dependencyId.version;
  }
  if (dependencyComponentMap.origin === (_constants || _load_constants()).COMPONENT_ORIGINS.AUTHORED) {
    return null;
  }
  var dependencyRootDir = dependencyComponentMap.rootDir;
  if (!dependencyRootDir) {
    throw new (_generalError || _load_generalError()).default(`rootDir is missing from an imported component ${dependencyId.toString()}`);
  }
  if (!parentComponentMap.rootDir) throw new (_generalError || _load_generalError()).default('rootDir is missing from an imported component');
  var rootDirRelative = (0, (_utils || _load_utils()).pathRelativeLinux)(parentComponentMap.rootDir, dependencyRootDir);
  return convertToValidPathForPackageManager(rootDirRelative);
}

function getRegistryPrefix() {
  return (0, (_globalConfig || _load_globalConfig()).getSync)((_constants || _load_constants()).CFG_REGISTRY_DOMAIN_PREFIX) || (_constants || _load_constants()).DEFAULT_REGISTRY_DOMAIN_PREFIX;
}

function convertIdToNpmName(id) {
  var withVersion = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

  var registryPrefix = getRegistryPrefix();
  var npmName = `${registryPrefix}/${id.toStringWithoutVersion().replace(/\//g, (_constants || _load_constants()).NODE_PATH_COMPONENT_SEPARATOR)}`;
  // $FlowFixMe the id here has a version
  return withVersion ? `${npmName}@${id.version}` : npmName;
}

exports.addComponentsToRoot = addComponentsToRoot;
exports.removeComponentsFromNodeModules = removeComponentsFromNodeModules;
exports.changeDependenciesToRelativeSyntax = changeDependenciesToRelativeSyntax;
exports.write = write;
exports.addComponentsWithVersionToRoot = addComponentsWithVersionToRoot;
exports.updateAttribute = updateAttribute;
exports.addWorkspacesToPackageJson = addWorkspacesToPackageJson;
exports.removeComponentsFromWorkspacesAndDependencies = removeComponentsFromWorkspacesAndDependencies;