"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.dependenciesSatisfied = dependenciesSatisfied;
exports.validIntInput = exports.sortByConfigOrder = exports.sortAndFilterConnectorConfiguration = exports.hasUiRestrictions = exports.filterSortValidateEntries = exports.ensureStringType = exports.ensureIntType = exports.ensureCorrectTyping = exports.ensureBooleanType = void 0;
var _i18n = require("@kbn/i18n");
var _searchConnectors = require("@kbn/search-connectors");
var _is_category_entry = require("../../../../../../../common/connectors/is_category_entry");
var _is_not_nullish = require("../../../../../../../common/utils/is_not_nullish");
/*
 * 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 validIntInput = value => {
  // reject non integers (including x.0 floats), but don't validate if empty
  return (value !== null || value !== '') && (isNaN(Number(value)) || !Number.isSafeInteger(Number(value)) || ensureStringType(value).indexOf('.') >= 0) ? false : true;
};
exports.validIntInput = validIntInput;
const ensureCorrectTyping = (type, value) => {
  switch (type) {
    case _searchConnectors.FieldType.INTEGER:
      return validIntInput(value) ? ensureIntType(value) : value;
    case _searchConnectors.FieldType.BOOLEAN:
      return ensureBooleanType(value);
    default:
      return ensureStringType(value);
  }
};
exports.ensureCorrectTyping = ensureCorrectTyping;
const ensureStringType = value => {
  return value !== null ? String(value) : '';
};
exports.ensureStringType = ensureStringType;
const ensureIntType = value => {
  // int is null-safe to prevent empty values from becoming zeroes
  if (value === null || value === '') {
    return null;
  }
  return parseInt(String(value), 10);
};
exports.ensureIntType = ensureIntType;
const ensureBooleanType = value => {
  return Boolean(value);
};
exports.ensureBooleanType = ensureBooleanType;
function dependenciesSatisfied(dependencies, dependencyLookup) {
  if (!dependencies) {
    return true;
  }
  for (const dependency of dependencies) {
    var _dependencyLookup$dep;
    // casting here because this is always going to be a ConnectorConfigProperties and not a Category
    if (dependency.value !== ((_dependencyLookup$dep = dependencyLookup[dependency.field]) === null || _dependencyLookup$dep === void 0 ? void 0 : _dependencyLookup$dep.value)) {
      return false;
    }
  }
  return true;
}
const sortByConfigOrder = (a, b) => {
  if ((0, _is_not_nullish.isNotNullish)(a.order)) {
    if ((0, _is_not_nullish.isNotNullish)(b.order)) {
      return a.order - b.order;
    }
    return -1;
  }
  if ((0, _is_not_nullish.isNotNullish)(b.order)) {
    // a doesn't have an order, but b has an order so takes precedence
    return 1;
  }
  return a.key.localeCompare(b.key);
};
exports.sortByConfigOrder = sortByConfigOrder;
const hasUiRestrictions = configEntry => {
  var _configEntry$ui_restr;
  return ((_configEntry$ui_restr = configEntry.ui_restrictions) !== null && _configEntry$ui_restr !== void 0 ? _configEntry$ui_restr : []).length > 0;
};
exports.hasUiRestrictions = hasUiRestrictions;
const filterSortValidateEntries = (configEntries, config, isNative) => {
  return configEntries.filter(configEntry => isNative ? !hasUiRestrictions(configEntry) && dependenciesSatisfied(configEntry.depends_on, config) : dependenciesSatisfied(configEntry.depends_on, config)).sort(sortByConfigOrder).map(configEntry => {
    const label = configEntry.label;
    const validationErrors = [];
    if (configEntry.type === _searchConnectors.FieldType.INTEGER && !validIntInput(configEntry.value)) {
      validationErrors.push(_i18n.i18n.translate('xpack.enterpriseSearch.content.indices.configurationConnector.config.invalidInteger', {
        defaultMessage: '{label} must be an integer.',
        values: {
          label
        }
      }));
    }
    return {
      ...configEntry,
      is_valid: validationErrors.length <= 0,
      validation_errors: validationErrors
    };
  });
};

/**
 *
 * Sorts and filters the connector configuration
 *
 * Sorting is done by specified order (if present)
 * otherwise by alphabetic order of keys
 *
 * Filtering is done on any fields with ui_restrictions
 * or that have not had their dependencies met
 *
 */
exports.filterSortValidateEntries = filterSortValidateEntries;
const sortAndFilterConnectorConfiguration = (config, isNative) => {
  // This casting is ugly but makes all of the iteration below work for TypeScript
  // extract_full_html is only defined for crawlers, who don't use this config screen
  // we explicitly filter it out as well
  const entries = Object.entries(config).filter(([key]) => key !== 'extract_full_html');
  const groupedConfigView = entries.map(([key, entry]) => {
    if (!entry || !(0, _is_category_entry.isCategoryEntry)(entry)) {
      return null;
    }
    const configEntries = entries.map(([configKey, configEntry]) => {
      if (!configEntry || (0, _is_category_entry.isCategoryEntry)(configEntry) || configEntry.category !== key) {
        return null;
      }
      return {
        key: configKey,
        ...configEntry
      };
    }).filter(_is_not_nullish.isNotNullish);
    return {
      ...entry,
      configEntries,
      key
    };
  }).filter(_is_not_nullish.isNotNullish);
  const unCategorizedItems = filterSortValidateEntries(entries.map(([key, entry]) => entry && !(0, _is_category_entry.isCategoryEntry)(entry) && !entry.category && !hasUiRestrictions(entry) ? {
    key,
    ...entry
  } : null).filter(_is_not_nullish.isNotNullish), config, isNative);
  const categories = groupedConfigView.map(category => {
    const configEntries = filterSortValidateEntries(category.configEntries, config, isNative);
    return configEntries.length > 0 ? {
      ...category,
      configEntries
    } : null;
  }).filter(_is_not_nullish.isNotNullish);
  const advancedConfigurations = isNative ? [] : filterSortValidateEntries(entries.map(([key, entry]) => {
    return entry && (0, _searchConnectors.isConfigEntry)(entry) && entry.ui_restrictions.includes('advanced') ? {
      key,
      ...entry
    } : null;
  }).filter(_is_not_nullish.isNotNullish), config, isNative);
  return {
    advancedConfigurations: advancedConfigurations || [],
    categories,
    unCategorizedItems
  };
};
exports.sortAndFilterConnectorConfiguration = sortAndFilterConnectorConfiguration;