"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getCommonFields = getCommonFields;
exports.getIndexNamesFromAliasesResponse = getIndexNamesFromAliasesResponse;
exports.getIndices = getIndices;
exports.normalizeFieldsList = normalizeFieldsList;
var _lodash = require("lodash");
var _fp = require("lodash/fp");
/*
 * 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; you may not use this file except in compliance with the Elastic License
 * 2.0.
 */

const normalizedFieldTypes = {
  long: 'number',
  integer: 'number',
  short: 'number',
  byte: 'number',
  double: 'number',
  float: 'number',
  half_float: 'number',
  scaled_float: 'number'
};
function getCommonFields(fieldsPerIndex) {
  return (0, _fp.flow)(
  // Flatten the fields arrays
  (0, _fp.flatMap)('fields'),
  // Group fields by name
  (0, _fp.groupBy)('name'),
  // Keep groups with more than 1 field
  (0, _fp.pickBy)(group => group.length > 1),
  // Convert the result object to an array of fields
  _fp.values,
  // Take the first item from each group (since we only need one match)
  (0, _fp.map)(group => group[0]))(fieldsPerIndex);
}
function normalizeFieldsList(fields) {
  const result = [];
  (0, _lodash.forEach)(fields, (field, name) => {
    // If the field exists in multiple indexes, the types may be inconsistent.
    // In this case, default to the first type.
    const type = (0, _lodash.keys)(field)[0];

    // Do not include fields that have a type that starts with an underscore (e.g. _id, _source)
    if (type.startsWith('_')) {
      return;
    }
    result.push({
      name,
      type,
      normalizedType: normalizedFieldTypes[type] || type
    });
  });
  return (0, _lodash.sortBy)(result, 'name');
}
function getIndexNamesFromAliasesResponse(json) {
  return (0, _lodash.reduce)(json, (list, {
    aliases
  }, indexName) => {
    // Add the index name to the list
    list.push(indexName);
    // If the index has aliases, add them to the list as well
    if ((0, _lodash.size)(aliases) > 0) {
      list.push(...Object.keys(aliases));
    }
    return list;
  }, []);
}
async function getIndices(dataClient, pattern, limit = 10) {
  // We will first rely on the indices aliases API to get the list of indices and their aliases.
  const aliasResult = await dataClient.asCurrentUser.indices.getAlias({
    index: pattern,
    expand_wildcards: 'open'
  }, {
    ignore: [404],
    meta: true
  });
  if (aliasResult.statusCode !== 404) {
    const indicesFromAliasResponse = getIndexNamesFromAliasesResponse(aliasResult.body);
    return indicesFromAliasResponse.slice(0, limit);
  }

  // If the indices aliases API fails or returns nothing, we will rely on the indices stats API to
  // get the list of indices.
  const response = await dataClient.asCurrentUser.search({
    index: pattern,
    body: {
      size: 0,
      aggs: {
        indices: {
          terms: {
            field: '_index',
            size: limit
          }
        }
      }
    }
  }, {
    ignore: [404],
    meta: true
  });
  if (response.statusCode === 404 || !response.body.aggregations) {
    return [];
  }
  const indices = response.body.aggregations.indices;
  return indices.buckets ? indices.buckets.map(bucket => bucket.key) : [];
}