"use strict";

exports.__esModule = true;
require("core-js/modules/es.array.push.js");
require("core-js/modules/es.error.cause.js");
var _array = require("../../helpers/array");
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
/**
 * @private
 * @class DataFilter
 */
class DataFilter {
  constructor(conditionCollection) {
    let columnDataFactory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : () => [];
    /**
     * Reference to the instance of {ConditionCollection}.
     *
     * @type {ConditionCollection}
     */
    _defineProperty(this, "conditionCollection", void 0);
    /**
     * Function which provide source data factory for specified column.
     *
     * @type {Function}
     */
    _defineProperty(this, "columnDataFactory", void 0);
    this.conditionCollection = conditionCollection;
    this.columnDataFactory = columnDataFactory;
  }

  /**
   * Filter data based on the conditions collection.
   *
   * @returns {Array}
   */
  filter() {
    let filteredData = [];
    (0, _array.arrayEach)(this.conditionCollection.getFilteredColumns(), (physicalColumn, index) => {
      let columnData = this.columnDataFactory(physicalColumn);
      if (index) {
        columnData = this._getIntersectData(columnData, filteredData);
      }
      filteredData = this.filterByColumn(physicalColumn, columnData);
    });
    return filteredData;
  }

  /**
   * Filter data based on specified physical column index.
   *
   * @param {number} column The physical column index.
   * @param {Array} [dataSource] Data source as array of objects with `value` and `meta` keys (e.g. `{value: 'foo', meta: {}}`).
   * @returns {Array} Returns filtered data.
   */
  filterByColumn(column) {
    let dataSource = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
    const filteredData = [];
    (0, _array.arrayEach)(dataSource, dataRow => {
      if (dataRow !== undefined && this.conditionCollection.isMatch(dataRow, column)) {
        filteredData.push(dataRow);
      }
    });
    return filteredData;
  }

  /**
   * Intersect data.
   *
   * @private
   * @param {Array} data The data to intersect.
   * @param {Array} needles The collection intersected rows with the data.
   * @returns {Array}
   */
  _getIntersectData(data, needles) {
    const result = [];
    (0, _array.arrayEach)(needles, needleRow => {
      const row = needleRow.meta.visualRow;
      if (data[row] !== undefined) {
        result[row] = data[row];
      }
    });
    return result;
  }
}
var _default = DataFilter;
exports.default = _default;