'use strict';

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

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 _ramda;

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

var _componentConfig;

function _load_componentConfig() {
  return _componentConfig = _interopRequireDefault(require('./component-config'));
}

var _constants;

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

var _consumerOverrides;

function _load_consumerOverrides() {
  return _consumerOverrides = require('./consumer-overrides');
}

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 ComponentOverrides = function () {
  function ComponentOverrides(overrides, overridesFromConsumer) {
    _classCallCheck(this, ComponentOverrides);

    this.overrides = overrides || {};
    this.overridesFromConsumer = overridesFromConsumer || {};
  }
  /**
   * overrides of component can be determined by three different sources.
   * 1. component-config. (bit.json/package.json of the component itself).
   *    authored normally don't have it, most imported have it, unless they choose not to write package.json/bit.json.
   * 2. consumer-config. (bit.json/package.json of the consumer when it has overrides of the component).
   * 3. model. (when the component is tagged, the overrides data is saved into the model).
   *
   * the strategy of loading them is simple:
   * if the component config is written to the filesystem, use it (#1).
   * if the component config is not written, it can be for two reasons:
   * a) it's imported and the user chose not to write package.json nor bit.json. in this case, use
   * component from the model.
   * b) it's author. by default, the config is written into consumer-config (if not exist) on import.
   * which, in this case, use only consumer-config.
   * an exception is when an author runs `eject-conf` command to explicitly write the config, then,
   * use the component-config.
   */


  _createClass(ComponentOverrides, [{
    key: 'getComponentDependenciesWithVersion',
    value: function getComponentDependenciesWithVersion() {
      var allDeps = Object.assign({}, this.overrides.dependencies, this.overrides.devDependencies, this.overrides.peerDependencies);
      return this._filterForComponentWithValidVersion(allDeps);
    }
  }, {
    key: 'getComponentDependenciesWithVersionFromConsumer',
    value: function getComponentDependenciesWithVersionFromConsumer() {
      var allDeps = Object.assign({}, this.overridesFromConsumer.dependencies, this.overridesFromConsumer.devDependencies, this.overridesFromConsumer.peerDependencies);
      return this._filterForComponentWithValidVersion(allDeps);
    }
  }, {
    key: '_filterForComponentWithValidVersion',
    value: function _filterForComponentWithValidVersion(deps) {
      var _this = this;

      return Object.keys(deps).reduce(function (acc, current) {
        if (_this._isValidVersion(deps[current]) && current.startsWith((_constants || _load_constants()).OVERRIDE_COMPONENT_PREFIX)) {
          var component = current.replace((_constants || _load_constants()).OVERRIDE_COMPONENT_PREFIX, '');
          acc[component] = deps[current];
        }
        return acc;
      }, {});
    }
  }, {
    key: '_isValidVersion',
    value: function _isValidVersion(ver) {
      return ver !== (_constants || _load_constants()).MANUALLY_ADD_DEPENDENCY && ver !== (_constants || _load_constants()).MANUALLY_REMOVE_DEPENDENCY;
    }
  }, {
    key: 'getIgnored',
    value: function getIgnored(field) {
      return (_ramda || _load_ramda()).default.keys((_ramda || _load_ramda()).default.filter(function (dep) {
        return dep === (_constants || _load_constants()).MANUALLY_REMOVE_DEPENDENCY;
      }, this.overrides[field] || {}));
    }
  }, {
    key: 'getIgnoredFiles',
    value: function getIgnoredFiles(field) {
      var ignoredRules = this.getIgnored(field);
      return ignoredRules.filter(function (rule) {
        return rule.startsWith((_constants || _load_constants()).OVERRIDE_FILE_PREFIX);
      }).map(function (rule) {
        return rule.replace((_constants || _load_constants()).OVERRIDE_FILE_PREFIX, '');
      });
    }
  }, {
    key: 'getIgnoredComponents',
    value: function getIgnoredComponents(field) {
      var _this2 = this;

      var ignoredRules = this.getIgnored(field);
      return (_ramda || _load_ramda()).default.flatten(ignoredRules.filter(function (rule) {
        return rule.startsWith((_constants || _load_constants()).OVERRIDE_COMPONENT_PREFIX);
      }).map(function (rule) {
        return rule.replace((_constants || _load_constants()).OVERRIDE_COMPONENT_PREFIX, '');
      }).map(function (idStr) {
        return [idStr].concat(_toConsumableArray(_this2._getComponentNamesFromPackages(idStr)));
      }));
    }

    /**
     * it is possible that a user added the component into the overrides as a package.
     * e.g. `@bit/david.utils.is-string` instead of `@bit/david.utils/is-string`
     * or, if not using bit.dev, `@bit/utils.is-string` instead of `@bit/utils/is-string`
     */

  }, {
    key: '_getComponentNamesFromPackages',
    value: function _getComponentNamesFromPackages(idStr) {
      var idSplitByDot = idStr.split('.');
      var numberOfDots = idSplitByDot.length - 1;
      if (numberOfDots === 0) return []; // nothing to do. it wasn't entered as a package
      var localScopeComponent = idSplitByDot.join('/'); // convert all dots to slashes
      if (numberOfDots === 1) {
        // it can't be from bit.dev, it must be locally
        return [localScopeComponent];
      }
      // there are two dots or more. it can be from bit.dev and it can be locally
      // for a remoteScopeComponent, leave the first dot and convert only the rest to a slash
      var remoteScopeComponent = `${(_ramda || _load_ramda()).default.head(idSplitByDot)}.${(_ramda || _load_ramda()).default.tail(idSplitByDot).join('/')}`;
      return [localScopeComponent, remoteScopeComponent];
    }
  }, {
    key: 'getIgnoredPackages',
    value: function getIgnoredPackages(field) {
      var ignoredRules = this.getIgnored(field);
      return ignoredRules.filter(function (rule) {
        return !rule.startsWith((_constants || _load_constants()).OVERRIDE_FILE_PREFIX) && !rule.startsWith((_constants || _load_constants()).OVERRIDE_COMPONENT_PREFIX);
      });
    }
  }, {
    key: 'stripOriginallySharedDir',
    value: function stripOriginallySharedDir(sharedDir) {
      var _this3 = this;

      if (!sharedDir) return;
      (_consumerOverrides || _load_consumerOverrides()).dependenciesFields.forEach(function (field) {
        if (!_this3.overrides[field]) return;
        Object.keys(_this3.overrides[field]).forEach(function (rule) {
          if (!rule.startsWith((_constants || _load_constants()).OVERRIDE_FILE_PREFIX)) return;
          var fileWithSharedDir = rule.replace((_constants || _load_constants()).OVERRIDE_FILE_PREFIX, '');
          // $FlowFixMe we made sure that sharedDir is not empty
          var fileWithoutSharedDir = fileWithSharedDir.replace(`${sharedDir}/`, '');
          // $FlowFixMe
          var value = _this3.overrides[field][rule];
          // $FlowFixMe
          delete _this3.overrides[field][rule];
          // $FlowFixMe
          _this3.overrides[field][`${(_constants || _load_constants()).OVERRIDE_FILE_PREFIX}${fileWithoutSharedDir}`] = value;
        });
      });
    }
  }, {
    key: 'addOriginallySharedDir',
    value: function addOriginallySharedDir(sharedDir) {
      var _this4 = this;

      if (!sharedDir) return;
      (_consumerOverrides || _load_consumerOverrides()).dependenciesFields.forEach(function (field) {
        if (!_this4.overrides[field]) return;
        Object.keys(_this4.overrides[field]).forEach(function (rule) {
          if (!rule.startsWith((_constants || _load_constants()).OVERRIDE_FILE_PREFIX)) return;
          var fileWithoutSharedDir = rule.replace((_constants || _load_constants()).OVERRIDE_FILE_PREFIX, '');
          // $FlowFixMe
          var fileWithSharedDir = `${sharedDir}/${fileWithoutSharedDir}`;
          // $FlowFixMe
          var value = _this4.overrides[field][rule];
          // $FlowFixMe
          delete _this4.overrides[field][rule];
          // $FlowFixMe
          _this4.overrides[field][`${(_constants || _load_constants()).OVERRIDE_FILE_PREFIX}${fileWithSharedDir}`] = value;
        });
      });
    }
  }, {
    key: 'clone',
    value: function clone() {
      return new ComponentOverrides((_ramda || _load_ramda()).default.clone(this.overrides), (_ramda || _load_ramda()).default.clone(this.overridesFromConsumer));
    }
  }, {
    key: 'componentOverridesData',
    get: function get() {
      var fields = ComponentOverrides.componentOverridesDataFields();
      var isDependencyField = function isDependencyField(val, field) {
        return fields.includes(field);
      };
      return (_ramda || _load_ramda()).default.pickBy(isDependencyField, this.overrides);
    }
  }], [{
    key: 'loadFromConsumer',
    value: function loadFromConsumer(overridesFromConsumer, overridesFromModel, componentConfig, isAuthor) {
      if (componentConfig && componentConfig.componentHasWrittenConfig) {
        // $FlowFixMe
        return new ComponentOverrides(componentConfig.overrides, overridesFromConsumer);
      }
      if (!isAuthor) {
        return ComponentOverrides.loadFromScope(overridesFromModel);
      }
      return new ComponentOverrides(overridesFromConsumer, overridesFromConsumer);
    }
  }, {
    key: 'loadFromScope',
    value: function loadFromScope() {
      var overridesFromModel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

      // $FlowFixMe
      return new ComponentOverrides((_ramda || _load_ramda()).default.clone(overridesFromModel), {});
    }
  }, {
    key: 'componentOverridesDataFields',
    value: function componentOverridesDataFields() {
      return (_consumerOverrides || _load_consumerOverrides()).dependenciesFields;
    }
  }, {
    key: 'getAllFilesPaths',
    value: function getAllFilesPaths(overrides) {
      if (!overrides) return [];
      var allDeps = Object.assign({}, overrides.dependencies, overrides.devDependencies, overrides.peerDependencies);
      return Object.keys(allDeps).filter(function (rule) {
        return rule.startsWith((_constants || _load_constants()).OVERRIDE_FILE_PREFIX);
      }).map(function (rule) {
        return rule.replace((_constants || _load_constants()).OVERRIDE_FILE_PREFIX, '');
      });
    }
  }]);

  return ComponentOverrides;
}();

exports.default = ComponentOverrides;