"use strict";

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

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

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

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 _groupArray() {
  const data = _interopRequireDefault(require("group-array"));

  _groupArray = function () {
    return data;
  };

  return data;
}

function _lodash() {
  const data = _interopRequireDefault(require("lodash.partition"));

  _lodash = function () {
    return data;
  };

  return data;
}

function _() {
  const data = require("..");

  _ = function () {
    return data;
  };

  return data;
}

function _bitIds() {
  const data = _interopRequireDefault(require("../../bit-id/bit-ids"));

  _bitIds = function () {
    return data;
  };

  return data;
}

function _removedComponents() {
  const data = require("../../scope/removed-components");

  _removedComponents = function () {
    return data;
  };

  return data;
}

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

  _logger = function () {
    return data;
  };

  return data;
}

function _constants() {
  const data = require("../../constants");

  _constants = function () {
    return data;
  };

  return data;
}

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

  _generalError = function () {
    return data;
  };

  return data;
}

function _scopeRemotes() {
  const data = require("../../scope/scope-remotes");

  _scopeRemotes = function () {
    return data;
  };

  return data;
}

function _enrichContextFromGlobal() {
  const data = _interopRequireDefault(require("../../hooks/utils/enrich-context-from-global"));

  _enrichContextFromGlobal = function () {
    return data;
  };

  return data;
}

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

  _consumerComponent = function () {
    return data;
  };

  return data;
}

function _deleteComponentFiles() {
  const data = _interopRequireDefault(require("../component-ops/delete-component-files"));

  _deleteComponentFiles = function () {
    return data;
  };

  return data;
}

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

  packageJsonUtils = function () {
    return data;
  };

  return data;
}

function _remotes() {
  const data = require("../../remotes");

  _remotes = function () {
    return data;
  };

  return data;
}

/**
 * Remove components local and remote
 * splits array of ids into local and remote and removes according to flags
 * @param {string[]} ids - list of remote component ids to delete
 * @param {boolean} force - delete component that are used by other components.
 * @param {boolean} remote - delete component from a remote scope
 * @param {boolean} track - keep tracking local staged components in bitmap.
 * @param {boolean} deleteFiles - delete local added files from fs.
 */
var _default =
/*#__PURE__*/
function () {
  var _removeComponents = (0, _bluebird().coroutine)(function* ({
    consumer,
    ids,
    force,
    remote,
    track,
    deleteFiles
  }) {
    _logger().default.debugAndAddBreadCrumb('removeComponents', `{ids}. force: ${force.toString()}`, {
      ids: ids.toString()
    }); // added this to remove support for remove only one version from a component


    const bitIdsLatest = _bitIds().default.fromArray(ids.map(id => {
      return id.changeVersion(_constants().LATEST_BIT_VERSION);
    }));

    const [localIds, remoteIds] = (0, _lodash().default)(bitIdsLatest, id => id.isLocal());

    if (remote && localIds.length) {
      throw new (_generalError().default)(`unable to remove the remote components: ${localIds.join(',')} as they don't contain a scope-name`);
    }

    const remoteResult = remote && !_ramda().default.isEmpty(remoteIds) ? yield removeRemote(consumer, remoteIds, force) : [];
    const localResult = !remote ? yield removeLocal(consumer, bitIdsLatest, force, track, deleteFiles) // $FlowFixMe
    : new (_removedComponents().RemovedLocalObjects)();
    return {
      localResult,
      remoteResult
    };
  });

  function removeComponents(_x) {
    return _removeComponents.apply(this, arguments);
  }

  return removeComponents;
}();
/**
 * Remove remote component from ssh server
 * this method groups remote components by remote name and deletes remote components together
 * @param {BitIds} bitIds - list of remote component ids to delete
 * @param {boolean} force - delete component that are used by other components.
 */


exports.default = _default;

function removeRemote(_x2, _x3, _x4) {
  return _removeRemote.apply(this, arguments);
}
/**
 * removeLocal - remove local (imported, new staged components) from modules and bitmap according to flags
 * @param {BitIds} bitIds - list of component ids to delete
 * @param {boolean} force - delete component that are used by other components.
 * @param {boolean} deleteFiles - delete component that are used by other components.
 */


function _removeRemote() {
  _removeRemote = (0, _bluebird().coroutine)(function* (consumer, bitIds, force) {
    const groupedBitsByScope = (0, _groupArray().default)(bitIds, 'scope');
    const remotes = consumer ? yield (0, _scopeRemotes().getScopeRemotes)(consumer.scope) : yield _remotes().Remotes.getGlobalRemotes();
    const context = {};
    (0, _enrichContextFromGlobal().default)(context);
    const scope = consumer ? consumer.scope : null;
    const removeP = Object.keys(groupedBitsByScope).map(
    /*#__PURE__*/
    function () {
      var _ref = (0, _bluebird().coroutine)(function* (key) {
        const resolvedRemote = yield remotes.resolve(key, scope);
        const idsStr = groupedBitsByScope[key].map(id => id.toStringWithoutVersion());
        return resolvedRemote.deleteMany(idsStr, force, context);
      });

      return function (_x10) {
        return _ref.apply(this, arguments);
      };
    }());
    return Promise.all(removeP);
  });
  return _removeRemote.apply(this, arguments);
}

function removeLocal(_x5, _x6, _x7, _x8, _x9) {
  return _removeLocal.apply(this, arguments);
}

function _removeLocal() {
  _removeLocal = (0, _bluebird().coroutine)(function* (consumer, bitIds, force, track, deleteFiles) {
    // local remove in case user wants to delete tagged components
    const modifiedComponents = new (_bitIds().default)();
    const nonModifiedComponents = new (_bitIds().default)(); // $FlowFixMe

    if (_ramda().default.isEmpty(bitIds)) return new (_removedComponents().RemovedLocalObjects)();

    if (!force) {
      yield Promise.all(bitIds.map(
      /*#__PURE__*/
      function () {
        var _ref2 = (0, _bluebird().coroutine)(function* (id) {
          try {
            const componentStatus = yield consumer.getComponentStatusById(id);
            if (componentStatus.modified) modifiedComponents.push(id);else nonModifiedComponents.push(id);
          } catch (err) {
            // if a component has an error, such as, missing main file, we do want to allow removing that component
            if (_consumerComponent().default.isComponentInvalidByErrorType(err)) {
              nonModifiedComponents.push(id);
            } else {
              throw err;
            }
          }
        });

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

    const {
      removedComponentIds,
      missingComponents,
      dependentBits,
      removedDependencies
    } = yield consumer.scope.removeMany(force ? bitIds : nonModifiedComponents, force, true, consumer);

    if (!_ramda().default.isEmpty(removedComponentIds)) {
      yield (0, _deleteComponentFiles().default)(consumer, removedComponentIds, deleteFiles);
      yield (0, _deleteComponentFiles().default)(consumer, removedDependencies, false);

      if (!track) {
        yield packageJsonUtils().removeComponentsFromWorkspacesAndDependencies(consumer, removedComponentIds);
        yield consumer.cleanFromBitMap(removedComponentIds, removedDependencies);
      }
    }

    return new (_removedComponents().RemovedLocalObjects)(removedComponentIds, missingComponents, modifiedComponents, removedDependencies, dependentBits);
  });
  return _removeLocal.apply(this, arguments);
}