"use strict";

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

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

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

  _ramda = function () {
    return data;
  };

  return data;
}

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

  _bitId = function () {
    return data;
  };

  return data;
}

function _foreach() {
  const data = _interopRequireDefault(require("../utils/object/foreach"));

  _foreach = function () {
    return data;
  };

  return data;
}

function _resolveLatestVersion() {
  const data = _interopRequireDefault(require("../utils/resolveLatestVersion"));

  _resolveLatestVersion = function () {
    return data;
  };

  return data;
}

class BitIds extends Array {
  serialize() {
    return this.map(bitId => bitId.toString());
  }

  toObject() {
    return _ramda().default.mergeAll(this.map(bitId => bitId.toObject()));
  }
  /**
   * Resolve an id with latest to specific version
   * This used to get the real version from the flatten deps by the deps ids
   *
   * @param {BitId} idWithLatest - A bit id object with latest version
   * @returns {BitId} - The bit id found in the array (with actual version)
   * @memberof BitIds
   */


  resolveVersion(idWithLatest) {
    // $FlowFixMe
    return (0, _resolveLatestVersion().default)(this, idWithLatest);
  }

  has(bitId) {
    return Boolean(this.search(bitId));
  }

  hasWithoutVersion(bitId) {
    return Boolean(this.searchWithoutVersion(bitId));
  }

  search(bitId) {
    return this.find(id => id.hasSameName(bitId) && id.hasSameScope(bitId) && id.hasSameVersion(bitId));
  }

  searchWithoutVersion(bitId) {
    return this.find(id => id.hasSameName(bitId) && id.hasSameScope(bitId));
  }

  searchWithoutScopeAndVersion(bitId) {
    return this.find(id => id.hasSameName(bitId));
  }

  searchWithoutScope(bitId) {
    return this.find(id => id.hasSameName(bitId) && id.hasSameVersion(bitId));
  }

  searchStrWithoutVersion(idStr) {
    return this.find(id => id.toStringWithoutVersion() === idStr);
  }

  searchStrWithoutScopeAndVersion(idStr) {
    return this.find(id => id.toStringWithoutScopeAndVersion() === idStr);
  }

  filterExact(bitId) {
    return this.filter(id => id.hasSameName(bitId) && id.hasSameScope(bitId) && id.hasSameVersion(bitId));
  }

  filterWithoutVersion(bitId) {
    return this.filter(id => id.hasSameName(bitId) && id.hasSameScope(bitId));
  }

  filterWithoutScopeAndVersion(bitId) {
    return this.filter(id => id.hasSameName(bitId));
  }

  removeIfExistWithoutVersion(bitId) {
    return BitIds.fromArray(this.filter(id => !id.isEqualWithoutVersion(bitId)));
  }
  /**
   * make sure to pass only bit ids you know they have scope, otherwise, you'll get invalid bit ids.
   * this is mainly useful for remote commands where it is impossible to have a component without scope.
   */


  static deserialize(array = []) {
    return new BitIds(...array.map(id => _bitId().default.parse(id, true)));
  }

  toString() {
    return this.map(id => id.toString()).join(', ');
  }

  static fromObject(dependencies) {
    const array = [];
    (0, _foreach().default)(dependencies, (version, id) => {
      array.push(_bitId().default.parse(id, true, version)); // bit.json has only imported dependencies, they all have scope
    });
    return new BitIds(...array);
  }

  static fromArray(bitIds) {
    return new BitIds(...bitIds);
  }

  static uniqFromArray(bitIds) {
    const uniq = _ramda().default.uniqBy(JSON.stringify, bitIds);

    return BitIds.fromArray(uniq);
  }

  clone() {
    const cloneIds = this.map(id => id.clone());
    return new BitIds(...cloneIds);
  }

}

exports.default = BitIds;