/*
 * Licensed to Elasticsearch B.V. under one or more contributor
 * license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright
 * ownership. Elasticsearch B.V. licenses this file to you under
 * the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
// Creates an filter where the given field matches the given value
export function buildPhraseFilter(field, value, indexPattern) {
  var filter = {
    meta: {
      index: indexPattern.id
    }
  };
  var convertedValue = getConvertedValueForField(field, value);

  if (field.scripted) {
    filter.script = getPhraseScript(field, value);
    filter.meta.field = field.name;
  } else {
    filter.query = {
      match: {}
    };
    filter.query.match[field.name] = {
      query: convertedValue,
      type: 'phrase'
    };
  }

  return filter;
}
export function getPhraseScript(field, value) {
  var convertedValue = getConvertedValueForField(field, value);
  var script = buildInlineScriptForPhraseFilter(field);
  return {
    script: {
      source: script,
      lang: field.lang,
      params: {
        value: convertedValue
      }
    }
  };
} // See https://github.com/elastic/elasticsearch/issues/20941 and https://github.com/elastic/kibana/issues/8677
// and https://github.com/elastic/elasticsearch/pull/22201
// for the reason behind this change. Aggs now return boolean buckets with a key of 1 or 0.

export function getConvertedValueForField(field, value) {
  if (typeof value !== 'boolean' && field.type === 'boolean') {
    if ([1, 'true'].includes(value)) {
      return true;
    } else if ([0, 'false'].includes(value)) {
      return false;
    } else {
      throw new Error("".concat(value, " is not a valid boolean value for boolean field ").concat(field.name));
    }
  }

  return value;
}
/**
 * Takes a scripted field and returns an inline script appropriate for use in a script query.
 * Handles lucene expression and Painless scripts. Other langs aren't guaranteed to generate valid
 * scripts.
 *
 * @param {object} scriptedField A Field object representing a scripted field
 * @returns {string} The inline script string
 */

export function buildInlineScriptForPhraseFilter(scriptedField) {
  // We must wrap painless scripts in a lambda in case they're more than a simple expression
  if (scriptedField.lang === 'painless') {
    return "boolean compare(Supplier s, def v) {return s.get() == v;}" + "compare(() -> { ".concat(scriptedField.script, " }, params.value);");
  } else {
    return "(".concat(scriptedField.script, ") == value");
  }
}