"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.mapFilter = mapFilter;
var _lodash = require("lodash");
var _map_combined = require("./mappers/map_combined");
var _map_spatial_filter = require("./mappers/map_spatial_filter");
var _map_match_all = require("./mappers/map_match_all");
var _map_phrase = require("./mappers/map_phrase");
var _map_phrases = require("./mappers/map_phrases");
var _map_range = require("./mappers/map_range");
var _map_exists = require("./mappers/map_exists");
var _map_query_string = require("./mappers/map_query_string");
var _map_default = require("./mappers/map_default");
var _generate_mapping_chain = require("./generate_mapping_chain");
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */

function mapFilter(filter) {
  /** Mappers **/

  // Each mapper is a simple promise function that test if the mapper can
  // handle the mapping or not. If it handles it then it will resolve with
  // and object that has the key and value for the filter. Otherwise it will
  // reject it with the original filter. We had to go down the promise interface
  // because mapTerms and mapRange need access to the indexPatterns to format
  // the values and that's only available through the field formatters.

  // The mappers to apply. Each mapper will either return
  // a result object with a key and value attribute or
  // undefined. If undefined is return then the next
  // mapper will get the opportunity to map the filter.
  // To create a new mapper you just need to create a function
  // that either handles the mapping operation or not
  // and add it here. ProTip: These are executed in order listed
  const mappers = [_map_combined.mapCombined, _map_spatial_filter.mapSpatialFilter, _map_match_all.mapMatchAll, _map_range.mapRange, _map_phrase.mapPhrase, _map_phrases.mapPhrases, _map_exists.mapExists, _map_query_string.mapQueryString, _map_default.mapDefault];
  const noop = () => {
    throw new Error('No mappings have been found for filter.');
  };

  // Create a chain of responsibility by reducing all the
  // mappers down into one function.
  const mapFn = (0, _lodash.reduceRight)(mappers, (memo, map) => (0, _generate_mapping_chain.generateMappingChain)(map, memo), noop);
  const mappedFilter = (0, _lodash.cloneDeep)(filter);
  const mapped = mapFn(mappedFilter);

  // Map the filter into an object with the key and value exposed so it's
  // easier to work with in the template
  mappedFilter.meta = filter.meta || {};
  mappedFilter.meta.type = mapped.type;
  mappedFilter.meta.key = mapped.key;
  // Display value or formatter function.
  mappedFilter.meta.value = mapped.value;
  mappedFilter.meta.params = mapped.params;
  mappedFilter.meta.disabled = Boolean(mappedFilter.meta.disabled);
  mappedFilter.meta.negate = Boolean(mappedFilter.meta.negate);
  mappedFilter.meta.alias = mappedFilter.meta.alias || null;
  return mappedFilter;
}