'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _regenerator;

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

var _bluebird;

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

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _path;

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

var _semver;

function _load_semver() {
  return _semver = _interopRequireDefault(require('semver'));
}

var _ramda;

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

var _modelComponent;

function _load_modelComponent() {
  return _modelComponent = _interopRequireDefault(require('../../scope/models/model-component'));
}

var _scope;

function _load_scope() {
  return _scope = _interopRequireDefault(require('../../scope/scope'));
}

var _component;

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

var _bitId;

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

var _bitMap;

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

var _utils;

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

var _constants;

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

var _noIdMatchWildcard;

function _load_noIdMatchWildcard() {
  return _noIdMatchWildcard = _interopRequireDefault(require('../../api/consumer/lib/exceptions/no-id-match-wildcard'));
}

var _scopeRemotes;

function _load_scopeRemotes() {
  return _scopeRemotes = require('../../scope/scope-remotes');
}

var _isBitIdMatchByWildcards;

function _load_isBitIdMatchByWildcards() {
  return _isBitIdMatchByWildcards = _interopRequireDefault(require('../../utils/bit/is-bit-id-match-by-wildcards'));
}

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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var ComponentsList = function () {
  function ComponentsList(consumer) {
    _classCallCheck(this, ComponentsList);

    this._fromFileSystem = {};

    this.consumer = consumer;
    this.scope = consumer.scope;
    this.bitMap = consumer.bitMap;
  }

  _createClass(ComponentsList, [{
    key: 'getModelComponents',
    value: function () {
      var _ref = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee() {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                if (this._modelComponents) {
                  _context.next = 4;
                  break;
                }

                _context.next = 3;
                return this.scope.list();

              case 3:
                this._modelComponents = _context.sent;

              case 4:
                return _context.abrupt('return', this._modelComponents);

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

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

      return getModelComponents;
    }()

    /**
     * List all bit ids stored in the model
     */

  }, {
    key: 'getFromObjects',
    value: function () {
      var _ref2 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee2() {
        var modelComponents;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                if (this._fromObjectsIds) {
                  _context2.next = 5;
                  break;
                }

                _context2.next = 3;
                return this.getModelComponents();

              case 3:
                modelComponents = _context2.sent;

                this._fromObjectsIds = modelComponents.map(function (componentObjects) {
                  return new (_bitId || _load_bitId()).BitId({
                    scope: componentObjects.scope,
                    name: componentObjects.name,
                    version: componentObjects.scope ? componentObjects.latest() : null
                  });
                });

              case 5:
                return _context2.abrupt('return', this._fromObjectsIds);

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

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

      return getFromObjects;
    }()
  }, {
    key: '_getAuthoredAndImportedFromFS',
    value: function () {
      var _ref3 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee3() {
        var _ref4, _ref5, authored, imported;

        return (_regenerator || _load_regenerator()).default.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                _context3.next = 2;
                return Promise.all([this.getFromFileSystem((_constants || _load_constants()).COMPONENT_ORIGINS.AUTHORED), this.getFromFileSystem((_constants || _load_constants()).COMPONENT_ORIGINS.IMPORTED)]);

              case 2:
                _ref4 = _context3.sent;
                _ref5 = _slicedToArray(_ref4, 2);
                authored = _ref5[0];
                imported = _ref5[1];

                authored = authored || [];
                imported = imported || [];
                return _context3.abrupt('return', authored.concat(imported));

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

      function _getAuthoredAndImportedFromFS() {
        return _ref3.apply(this, arguments);
      }

      return _getAuthoredAndImportedFromFS;
    }()

    /**
     * Components that are in the model (either, tagged from a local scope or imported), and were
     * changed in the file system
     *
     * @param {boolean} [load=false] - Whether to load the component (false will return only the id)
     * @return {Promise<string[]>}
     */

  }, {
    key: 'listModifiedComponents',
    value: function () {
      var _ref6 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee4() {
        var _this = this;

        var load = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
        var fileSystemComponents;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                if (this._modifiedComponents) {
                  _context4.next = 7;
                  break;
                }

                _context4.next = 3;
                return this._getAuthoredAndImportedFromFS();

              case 3:
                fileSystemComponents = _context4.sent;
                _context4.next = 6;
                return (0, (_utils || _load_utils()).filterAsync)(fileSystemComponents, function (component) {
                  return _this.consumer.getComponentStatusById(component.id).then(function (status) {
                    return status.modified;
                  });
                });

              case 6:
                this._modifiedComponents = _context4.sent;

              case 7:
                if (!load) {
                  _context4.next = 9;
                  break;
                }

                return _context4.abrupt('return', this._modifiedComponents);

              case 9:
                return _context4.abrupt('return', this._modifiedComponents.map(function (component) {
                  return component.id;
                }));

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

      function listModifiedComponents() {
        return _ref6.apply(this, arguments);
      }

      return listModifiedComponents;
    }()
  }, {
    key: 'listOutdatedComponents',
    value: function () {
      var _ref7 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee5() {
        var fileSystemComponents, componentsFromModel;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                _context5.next = 2;
                return this._getAuthoredAndImportedFromFS();

              case 2:
                fileSystemComponents = _context5.sent;
                _context5.next = 5;
                return this.getModelComponents();

              case 5:
                componentsFromModel = _context5.sent;
                return _context5.abrupt('return', fileSystemComponents.filter(function (component) {
                  var modelComponent = componentsFromModel.find(function (c) {
                    return c.toBitId().isEqualWithoutVersion(component.id);
                  });
                  if (!modelComponent) return false;
                  var latestVersion = modelComponent.latest();
                  if (component.id.hasVersion() && (_semver || _load_semver()).default.gt(latestVersion, component.id.version)) {
                    component.latestVersion = latestVersion;
                    return true;
                  }
                  return false;
                }));

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

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

      return listOutdatedComponents;
    }()
  }, {
    key: 'newModifiedAndAutoTaggedComponents',
    value: function () {
      var _ref8 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee6() {
        var _ref9, _ref10, newComponents, modifiedComponents, autoTagPendingModel, autoTagPending, components;

        return (_regenerator || _load_regenerator()).default.wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                _context6.next = 2;
                return Promise.all([this.listNewComponents(true), this.listModifiedComponents(true)]);

              case 2:
                _ref9 = _context6.sent;
                _ref10 = _slicedToArray(_ref9, 2);
                newComponents = _ref10[0];
                modifiedComponents = _ref10[1];
                _context6.next = 8;
                return this.listAutoTagPendingComponents();

              case 8:
                autoTagPendingModel = _context6.sent;
                _context6.next = 11;
                return this.scope.toConsumerComponents(autoTagPendingModel);

              case 11:
                autoTagPending = _context6.sent;
                components = [].concat(_toConsumableArray(newComponents), _toConsumableArray(modifiedComponents), _toConsumableArray(autoTagPending));
                return _context6.abrupt('return', Promise.all(components));

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

      function newModifiedAndAutoTaggedComponents() {
        return _ref8.apply(this, arguments);
      }

      return newModifiedAndAutoTaggedComponents;
    }()
  }, {
    key: 'authoredAndImportedComponents',
    value: function () {
      var _ref11 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee7() {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee7$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                return _context7.abrupt('return', this._getAuthoredAndImportedFromFS());

              case 1:
              case 'end':
                return _context7.stop();
            }
          }
        }, _callee7, this);
      }));

      function authoredAndImportedComponents() {
        return _ref11.apply(this, arguments);
      }

      return authoredAndImportedComponents;
    }()
  }, {
    key: 'idsFromObjects',
    value: function () {
      var _ref12 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee8() {
        var fromObjects;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee8$(_context8) {
          while (1) {
            switch (_context8.prev = _context8.next) {
              case 0:
                _context8.next = 2;
                return this.getFromObjects();

              case 2:
                fromObjects = _context8.sent;
                return _context8.abrupt('return', new (Function.prototype.bind.apply((_bitId || _load_bitId()).BitIds, [null].concat(_toConsumableArray(fromObjects))))());

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

      function idsFromObjects() {
        return _ref12.apply(this, arguments);
      }

      return idsFromObjects;
    }()

    /**
     * Components that are registered in bit.map but have never been tagged
     *
     * @param {boolean} [load=false] - Whether to load the component (false will return only the id)
     * @return {Promise.<string[] | Component[]>}
     * @memberof ComponentsList
     */

  }, {
    key: 'listNewComponents',
    value: function () {
      var _ref13 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee9() {
        var load = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

        var idsFromBitMap, idsFromObjects, newComponents, newComponentsIds, _ref14, components;

        return (_regenerator || _load_regenerator()).default.wrap(function _callee9$(_context9) {
          while (1) {
            switch (_context9.prev = _context9.next) {
              case 0:
                idsFromBitMap = this.idsFromBitMap();
                _context9.next = 3;
                return this.idsFromObjects();

              case 3:
                idsFromObjects = _context9.sent;
                newComponents = [];

                idsFromBitMap.forEach(function (id) {
                  if (!idsFromObjects.searchWithoutScopeAndVersion(id)) {
                    newComponents.push(id);
                  }
                });
                newComponentsIds = new (Function.prototype.bind.apply((_bitId || _load_bitId()).BitIds, [null].concat(newComponents)))();

                if (!(!load || !newComponents.length)) {
                  _context9.next = 9;
                  break;
                }

                return _context9.abrupt('return', newComponentsIds);

              case 9:
                _context9.next = 11;
                return this.consumer.loadComponents(newComponentsIds, false);

              case 11:
                _ref14 = _context9.sent;
                components = _ref14.components;
                return _context9.abrupt('return', components);

              case 14:
              case 'end':
                return _context9.stop();
            }
          }
        }, _callee9, this);
      }));

      function listNewComponents() {
        return _ref13.apply(this, arguments);
      }

      return listNewComponents;
    }()

    /**
     * Authored exported components (easily identified by having a scope) which are not saved in the model are
     * import-pending. Exclude them from the 'newComponents' and add them to 'importPendingComponents'.
     */

  }, {
    key: 'listNewComponentsAndImportPending',
    value: function () {
      var _ref15 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee10() {
        var allNewComponents, newComponents, importPendingComponents;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee10$(_context10) {
          while (1) {
            switch (_context10.prev = _context10.next) {
              case 0:
                _context10.next = 2;
                return this.listNewComponents(true);

              case 2:
                allNewComponents = _context10.sent;
                newComponents = [];
                importPendingComponents = [];

                allNewComponents.forEach(function (component) {
                  if (component.id.scope) {
                    importPendingComponents.push(component);
                  } else {
                    newComponents.push(component);
                  }
                });
                return _context10.abrupt('return', { newComponents, importPendingComponents });

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

      function listNewComponentsAndImportPending() {
        return _ref15.apply(this, arguments);
      }

      return listNewComponentsAndImportPending;
    }()
  }, {
    key: 'listCommitPendingOfAllScope',
    value: function () {
      var _ref16 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee11(version) {
        var includeImported = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
        var tagPendingComponents, importedComponents, tagPendingComponentsLatest, warnings;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee11$(_context11) {
          while (1) {
            switch (_context11.prev = _context11.next) {
              case 0:
                tagPendingComponents = void 0;

                tagPendingComponents = this.idsFromBitMap((_constants || _load_constants()).COMPONENT_ORIGINS.AUTHORED);
                if (includeImported) {
                  importedComponents = this.idsFromBitMap((_constants || _load_constants()).COMPONENT_ORIGINS.IMPORTED);

                  tagPendingComponents = tagPendingComponents.concat(importedComponents);
                }
                _context11.next = 5;
                return this.scope.latestVersions(tagPendingComponents, false);

              case 5:
                tagPendingComponentsLatest = _context11.sent;
                warnings = [];

                tagPendingComponentsLatest.forEach(function (componentId) {
                  if ((_semver || _load_semver()).default.gt(componentId.version, version)) {
                    warnings.push(`warning: ${componentId.toString()} has a version greater than ${version}`);
                  }
                });
                return _context11.abrupt('return', { tagPendingComponents, warnings });

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

      function listCommitPendingOfAllScope(_x3) {
        return _ref16.apply(this, arguments);
      }

      return listCommitPendingOfAllScope;
    }()

    /**
     * New and modified components are tag pending
     *
     * @return {Promise<string[]>}
     */

  }, {
    key: 'listCommitPendingComponents',
    value: function () {
      var _ref17 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee12() {
        var _ref18, _ref19, newComponents, modifiedComponents;

        return (_regenerator || _load_regenerator()).default.wrap(function _callee12$(_context12) {
          while (1) {
            switch (_context12.prev = _context12.next) {
              case 0:
                _context12.next = 2;
                return Promise.all([this.listNewComponents(), this.listModifiedComponents()]);

              case 2:
                _ref18 = _context12.sent;
                _ref19 = _slicedToArray(_ref18, 2);
                newComponents = _ref19[0];
                modifiedComponents = _ref19[1];
                return _context12.abrupt('return', (_bitId || _load_bitId()).BitIds.fromArray([].concat(_toConsumableArray(newComponents), _toConsumableArray(modifiedComponents))));

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

      function listCommitPendingComponents() {
        return _ref17.apply(this, arguments);
      }

      return listCommitPendingComponents;
    }()
  }, {
    key: 'listExportPendingComponentsIds',
    value: function () {
      var _ref20 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee13() {
        var modelComponents, pendingExportComponents, ids;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee13$(_context13) {
          while (1) {
            switch (_context13.prev = _context13.next) {
              case 0:
                _context13.next = 2;
                return this.getModelComponents();

              case 2:
                modelComponents = _context13.sent;
                pendingExportComponents = modelComponents.filter(function (component) {
                  return component.isLocallyChanged();
                });
                ids = (_bitId || _load_bitId()).BitIds.fromArray(pendingExportComponents.map(function (c) {
                  return c.toBitId();
                }));
                return _context13.abrupt('return', this.updateIdsFromModelIfTheyOutOfSync(ids));

              case 6:
              case 'end':
                return _context13.stop();
            }
          }
        }, _callee13, this);
      }));

      function listExportPendingComponentsIds() {
        return _ref20.apply(this, arguments);
      }

      return listExportPendingComponentsIds;
    }()
  }, {
    key: 'updateIdsFromModelIfTheyOutOfSync',
    value: function () {
      var _ref21 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee15(ids) {
        var _this2 = this;

        var authoredAndImported, updatedIdsP, updatedIds;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee15$(_context15) {
          while (1) {
            switch (_context15.prev = _context15.next) {
              case 0:
                authoredAndImported = this.bitMap.getAuthoredAndImportedBitIds();
                updatedIdsP = ids.map(function () {
                  var _ref22 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee14(id) {
                    var idFromBitMap, component;
                    return (_regenerator || _load_regenerator()).default.wrap(function _callee14$(_context14) {
                      while (1) {
                        switch (_context14.prev = _context14.next) {
                          case 0:
                            idFromBitMap = authoredAndImported.searchWithoutScopeAndVersion(id);

                            if (!(idFromBitMap && !idFromBitMap.hasVersion())) {
                              _context14.next = 6;
                              break;
                            }

                            _context14.next = 4;
                            return _this2.consumer.loadComponent(id.changeVersion((_constants || _load_constants()).LATEST));

                          case 4:
                            component = _context14.sent;
                            return _context14.abrupt('return', component.id);

                          case 6:
                            return _context14.abrupt('return', id);

                          case 7:
                          case 'end':
                            return _context14.stop();
                        }
                      }
                    }, _callee14, _this2);
                  }));

                  return function (_x6) {
                    return _ref22.apply(this, arguments);
                  };
                }());
                _context15.next = 4;
                return Promise.all(updatedIdsP);

              case 4:
                updatedIds = _context15.sent;
                return _context15.abrupt('return', (_bitId || _load_bitId()).BitIds.fromArray(updatedIds));

              case 6:
              case 'end':
                return _context15.stop();
            }
          }
        }, _callee15, this);
      }));

      function updateIdsFromModelIfTheyOutOfSync(_x5) {
        return _ref21.apply(this, arguments);
      }

      return updateIdsFromModelIfTheyOutOfSync;
    }()
  }, {
    key: 'listExportPendingComponents',
    value: function () {
      var _ref23 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee16() {
        var _this3 = this;

        var exportPendingComponentsIds;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee16$(_context16) {
          while (1) {
            switch (_context16.prev = _context16.next) {
              case 0:
                _context16.next = 2;
                return this.listExportPendingComponentsIds();

              case 2:
                exportPendingComponentsIds = _context16.sent;
                return _context16.abrupt('return', Promise.all(exportPendingComponentsIds.map(function (id) {
                  return _this3.scope.getModelComponentIfExist(id);
                })));

              case 4:
              case 'end':
                return _context16.stop();
            }
          }
        }, _callee16, this);
      }));

      function listExportPendingComponents() {
        return _ref23.apply(this, arguments);
      }

      return listExportPendingComponents;
    }()
  }, {
    key: 'listAutoTagPendingComponents',
    value: function () {
      var _ref24 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee17() {
        var modifiedComponents, modifiedComponentsLatestVersions;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee17$(_context17) {
          while (1) {
            switch (_context17.prev = _context17.next) {
              case 0:
                _context17.next = 2;
                return this.listModifiedComponents();

              case 2:
                modifiedComponents = _context17.sent;

                if (!(!modifiedComponents || !modifiedComponents.length)) {
                  _context17.next = 5;
                  break;
                }

                return _context17.abrupt('return', []);

              case 5:
                _context17.next = 7;
                return this.scope.latestVersions(modifiedComponents);

              case 7:
                modifiedComponentsLatestVersions = _context17.sent;
                return _context17.abrupt('return', this.consumer.listComponentsForAutoTagging(modifiedComponentsLatestVersions));

              case 9:
              case 'end':
                return _context17.stop();
            }
          }
        }, _callee17, this);
      }));

      function listAutoTagPendingComponents() {
        return _ref24.apply(this, arguments);
      }

      return listAutoTagPendingComponents;
    }()
  }, {
    key: 'idsFromBitMap',
    value: function idsFromBitMap(origin) {
      var fromBitMap = this.getFromBitMap(origin);
      return fromBitMap;
    }

    /**
     * Finds all components that are saved in the file system.
     * Components might be stored in the default component directory and also might be outside
     * of that directory. The bit.map is used to find them all
     * If they are on bit.map but not on the file-system, populate them to _invalidComponents property
     */

  }, {
    key: 'getFromFileSystem',
    value: function () {
      var _ref25 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee18(origin) {
        var cacheKeyName, idsFromBitMap, _ref26, components, invalidComponents;

        return (_regenerator || _load_regenerator()).default.wrap(function _callee18$(_context18) {
          while (1) {
            switch (_context18.prev = _context18.next) {
              case 0:
                cacheKeyName = origin || 'all';

                if (this._fromFileSystem[cacheKeyName]) {
                  _context18.next = 10;
                  break;
                }

                idsFromBitMap = this.idsFromBitMap(origin);
                _context18.next = 5;
                return this.consumer.loadComponents(idsFromBitMap, false);

              case 5:
                _ref26 = _context18.sent;
                components = _ref26.components;
                invalidComponents = _ref26.invalidComponents;

                this._fromFileSystem[cacheKeyName] = components;
                if (!this._invalidComponents && !origin) {
                  this._invalidComponents = invalidComponents;
                }

              case 10:
                return _context18.abrupt('return', this._fromFileSystem[cacheKeyName]);

              case 11:
              case 'end':
                return _context18.stop();
            }
          }
        }, _callee18, this);
      }));

      function getFromFileSystem(_x7) {
        return _ref25.apply(this, arguments);
      }

      return getFromFileSystem;
    }()

    /**
     * components that are on bit.map but not on the file-system
     */

  }, {
    key: 'listInvalidComponents',
    value: function () {
      var _ref27 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee19() {
        return (_regenerator || _load_regenerator()).default.wrap(function _callee19$(_context19) {
          while (1) {
            switch (_context19.prev = _context19.next) {
              case 0:
                if (this._invalidComponents) {
                  _context19.next = 3;
                  break;
                }

                _context19.next = 3;
                return this.getFromFileSystem();

              case 3:
                return _context19.abrupt('return', this._invalidComponents);

              case 4:
              case 'end':
                return _context19.stop();
            }
          }
        }, _callee19, this);
      }));

      function listInvalidComponents() {
        return _ref27.apply(this, arguments);
      }

      return listInvalidComponents;
    }()
  }, {
    key: 'getFromBitMap',
    value: function getFromBitMap(origin) {
      var originParam = origin ? [origin] : undefined;
      return this.bitMap.getAllBitIds(originParam);
    }
  }, {
    key: 'getPathsForAllFilesOfAllComponents',
    value: function getPathsForAllFilesOfAllComponents(origin) {
      var _this4 = this;

      var absolute = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

      // TODO: maybe cache this as well
      var componentsFromBitMap = this.bitMap.getAllComponents(origin);
      var res = [];
      var getPaths = function getPaths(agg, isAbsolute) {
        return function (componentMap, componentId) {
          var relativePaths = componentMap.getFilesRelativeToConsumer();
          if (!isAbsolute) {
            agg.push.apply(agg, _toConsumableArray(relativePaths));
            return;
          }
          var consumerPath = _this4.consumer.getPath();
          var absPaths = relativePaths.map(function (relativePath) {
            return (_path || _load_path()).default.join(consumerPath, relativePath);
          });
          agg.push.apply(agg, _toConsumableArray(absPaths));
        };
      };
      (_ramda || _load_ramda()).default.forEachObjIndexed(getPaths(res, absolute), componentsFromBitMap);
      return res;
    }

    /**
     * get called when the Consumer is available, shows also components from remote scopes
     */

  }, {
    key: 'listScope',
    value: function () {
      var _ref28 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee20(showRemoteVersion, includeNested) {
        var _this5 = this;

        var components, componentsSorted, listScopeResults, componentsIds, latestVersionsInfo, authoredAndImportedIds;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee20$(_context20) {
          while (1) {
            switch (_context20.prev = _context20.next) {
              case 0:
                _context20.next = 2;
                return this.getModelComponents();

              case 2:
                components = _context20.sent;
                componentsSorted = ComponentsList.sortComponentsByName(components);
                listScopeResults = componentsSorted.map(function (component) {
                  return {
                    id: component.toBitIdWithLatestVersion(),
                    deprecated: component.deprecated
                  };
                });
                componentsIds = listScopeResults.map(function (result) {
                  return result.id;
                });

                if (!showRemoteVersion) {
                  _context20.next = 11;
                  break;
                }

                _context20.next = 9;
                return (0, (_scopeRemotes || _load_scopeRemotes()).fetchRemoteVersions)(this.scope, componentsIds);

              case 9:
                latestVersionsInfo = _context20.sent;

                latestVersionsInfo.forEach(function (componentId) {
                  var listResult = listScopeResults.find(function (c) {
                    return c.id.isEqualWithoutVersion(componentId);
                  });
                  if (!listResult) throw new Error(`failed finding ${componentId.toString()} in componentsIds`);
                  // $FlowFixMe version must be set as it came from a remote
                  listResult.remoteVersion = componentId.version;
                });

              case 11:
                authoredAndImportedIds = this.bitMap.getAuthoredAndImportedBitIds();

                listScopeResults.forEach(function (listResult) {
                  var existingBitMapId = authoredAndImportedIds.searchWithoutVersion(listResult.id);
                  if (existingBitMapId) {
                    listResult.currentlyUsedVersion = existingBitMapId.version;
                  }
                });

                if (!includeNested) {
                  _context20.next = 15;
                  break;
                }

                return _context20.abrupt('return', listScopeResults);

              case 15:
                return _context20.abrupt('return', listScopeResults.filter(function (listResult) {
                  var componentMap = _this5.bitMap.getComponentIfExist(listResult.id, { ignoreVersion: true });
                  return componentMap && componentMap.origin !== (_constants || _load_constants()).COMPONENT_ORIGINS.NESTED;
                }));

              case 16:
              case 'end':
                return _context20.stop();
            }
          }
        }, _callee20, this);
      }));

      function listScope(_x9, _x10) {
        return _ref28.apply(this, arguments);
      }

      return listScope;
    }()

    /**
     * get called from a bare-scope, shows only components of that scope
     */

  }, {
    key: 'listComponentsByIdsWithWildcard',
    value: function listComponentsByIdsWithWildcard(idsWithWildcard) {
      var allIds = this.bitMap.getAuthoredAndImportedBitIds();
      var matchedIds = ComponentsList.filterComponentsByWildcard(allIds, idsWithWildcard);
      if (!matchedIds.length) throw new (_noIdMatchWildcard || _load_noIdMatchWildcard()).default(idsWithWildcard);
      // $FlowFixMe filterComponentsByWildcard got BitId so it returns BitId
      return matchedIds;
    }
  }], [{
    key: 'listLocalScope',
    value: function () {
      var _ref29 = (0, (_bluebird || _load_bluebird()).coroutine)( /*#__PURE__*/(_regenerator || _load_regenerator()).default.mark(function _callee21(scope, namespacesUsingWildcards) {
        var components, componentsFilteredByWildcards, componentsSorted;
        return (_regenerator || _load_regenerator()).default.wrap(function _callee21$(_context21) {
          while (1) {
            switch (_context21.prev = _context21.next) {
              case 0:
                _context21.next = 2;
                return scope.listLocal();

              case 2:
                components = _context21.sent;
                componentsFilteredByWildcards = namespacesUsingWildcards ? ComponentsList.filterComponentsByWildcard(components, namespacesUsingWildcards) : components;
                componentsSorted = ComponentsList.sortComponentsByName(componentsFilteredByWildcards);
                return _context21.abrupt('return', componentsSorted.map(function (component) {
                  return {
                    id: component.toBitIdWithLatestVersion(),
                    deprecated: component.deprecated
                  };
                }));

              case 6:
              case 'end':
                return _context21.stop();
            }
          }
        }, _callee21, this);
      }));

      function listLocalScope(_x11, _x12) {
        return _ref29.apply(this, arguments);
      }

      return listLocalScope;
    }()

    // components can be one of the following: Component[] | ModelComponent[] | string[]

  }, {
    key: 'sortComponentsByName',
    value: function sortComponentsByName(components) {
      var getName = function getName(component) {
        var name = void 0;
        if ((_ramda || _load_ramda()).default.is((_modelComponent || _load_modelComponent()).default, component)) name = component.id();else if ((_ramda || _load_ramda()).default.is((_component || _load_component()).default, component)) name = component.id.toString();else name = component;
        return name.toUpperCase(); // ignore upper and lowercase
      };
      // $FlowFixMe
      return components.sort(function (a, b) {
        var nameA = getName(a);
        var nameB = getName(b);
        if (nameA < nameB) {
          return -1;
        }
        if (nameA > nameB) {
          return 1;
        }

        // names must be equal
        return 0;
      });
    }
  }, {
    key: 'filterComponentsByWildcard',
    value: function filterComponentsByWildcard(components, idsWithWildcard) {
      var getBitId = function getBitId(component) {
        if ((_ramda || _load_ramda()).default.is((_modelComponent || _load_modelComponent()).default, component)) return component.toBitId();
        if ((_ramda || _load_ramda()).default.is((_component || _load_component()).default, component)) return component.id;
        if ((_ramda || _load_ramda()).default.is((_bitId || _load_bitId()).BitId, component)) return component;
        throw new TypeError(`filterComponentsByWildcard got component with the wrong type: ${typeof component}`);
      };
      // $FlowFixMe
      return components.filter(function (component) {
        var bitId = getBitId(component);
        return (0, (_isBitIdMatchByWildcards || _load_isBitIdMatchByWildcards()).default)(bitId, idsWithWildcard);
      });
    }
  }, {
    key: 'getUniqueComponents',
    value: function getUniqueComponents(components) {
      return (_ramda || _load_ramda()).default.uniqBy(function (component) {
        return JSON.stringify(component.id);
      }, components);
    }
  }]);

  return ComponentsList;
}();

exports.default = ComponentsList;