"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.registerFieldForWildcard = exports.parseFields = void 0;
var _configSchema = require("@kbn/config-schema");
var _constants = require("../../constants");
var _fetcher = require("../../fetcher");
var _constants2 = require("../../../common/constants");
/*
 * 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.
 */

/**
 * Accepts one of the following:
 * 1. An array of field names
 * 2. A JSON-stringified array of field names
 * 3. A single field name (not comma-separated)
 * @returns an array of field names
 * @param fields
 */
const parseFields = fields => {
  if (Array.isArray(fields)) return fields;
  try {
    return JSON.parse(fields);
  } catch (e) {
    if (!fields.includes(',')) return [fields];
    throw new Error('metaFields should be an array of field names, a JSON-stringified array of field names, or a single field name');
  }
};
exports.parseFields = parseFields;
const access = 'internal';
const querySchema = _configSchema.schema.object({
  pattern: _configSchema.schema.string(),
  meta_fields: _configSchema.schema.oneOf([_configSchema.schema.string(), _configSchema.schema.arrayOf(_configSchema.schema.string())], {
    defaultValue: []
  }),
  type: _configSchema.schema.maybe(_configSchema.schema.string()),
  rollup_index: _configSchema.schema.maybe(_configSchema.schema.string()),
  allow_no_index: _configSchema.schema.maybe(_configSchema.schema.boolean()),
  include_unmapped: _configSchema.schema.maybe(_configSchema.schema.boolean()),
  fields: _configSchema.schema.maybe(_configSchema.schema.oneOf([_configSchema.schema.string(), _configSchema.schema.arrayOf(_configSchema.schema.string())]))
});
const fieldSubTypeSchema = _configSchema.schema.object({
  multi: _configSchema.schema.maybe(_configSchema.schema.object({
    parent: _configSchema.schema.string()
  })),
  nested: _configSchema.schema.maybe(_configSchema.schema.object({
    path: _configSchema.schema.string()
  }))
});
const FieldDescriptorSchema = _configSchema.schema.object({
  aggregatable: _configSchema.schema.boolean(),
  name: _configSchema.schema.string(),
  readFromDocValues: _configSchema.schema.boolean(),
  searchable: _configSchema.schema.boolean(),
  type: _configSchema.schema.string(),
  esTypes: _configSchema.schema.maybe(_configSchema.schema.arrayOf(_configSchema.schema.string())),
  subType: fieldSubTypeSchema,
  metadata_field: _configSchema.schema.maybe(_configSchema.schema.boolean()),
  fixedInterval: _configSchema.schema.maybe(_configSchema.schema.arrayOf(_configSchema.schema.string())),
  timeZone: _configSchema.schema.maybe(_configSchema.schema.arrayOf(_configSchema.schema.string())),
  timeSeriesMetric: _configSchema.schema.maybe(_configSchema.schema.oneOf([_configSchema.schema.literal('histogram'), _configSchema.schema.literal('summary'), _configSchema.schema.literal('counter'), _configSchema.schema.literal('gauge'), _configSchema.schema.literal('position')])),
  timeSeriesDimension: _configSchema.schema.maybe(_configSchema.schema.boolean()),
  conflictDescriptions: _configSchema.schema.maybe(_configSchema.schema.recordOf(_configSchema.schema.string(), _configSchema.schema.arrayOf(_configSchema.schema.string())))
});
const validate = {
  request: {
    query: querySchema,
    // not available to get request
    body: _configSchema.schema.maybe(_configSchema.schema.object({
      index_filter: _configSchema.schema.any()
    }))
  },
  response: {
    200: {
      body: _configSchema.schema.object({
        fields: _configSchema.schema.arrayOf(FieldDescriptorSchema),
        indices: _configSchema.schema.arrayOf(_configSchema.schema.string())
      })
    }
  }
};
const handler = isRollupsEnabled => async (context, request, response) => {
  var _request$body;
  const {
    asCurrentUser
  } = (await context.core).elasticsearch.client;
  const indexPatterns = new _fetcher.IndexPatternsFetcher(asCurrentUser, undefined, isRollupsEnabled());
  const {
    pattern,
    meta_fields: metaFields,
    type,
    rollup_index: rollupIndex,
    allow_no_index: allowNoIndex,
    include_unmapped: includeUnmapped
  } = request.query;

  // not available to get request
  const indexFilter = (_request$body = request.body) === null || _request$body === void 0 ? void 0 : _request$body.index_filter;
  let parsedFields = [];
  let parsedMetaFields = [];
  try {
    var _request$query$fields;
    parsedMetaFields = parseFields(metaFields);
    parsedFields = parseFields((_request$query$fields = request.query.fields) !== null && _request$query$fields !== void 0 ? _request$query$fields : []);
  } catch (error) {
    return response.badRequest();
  }
  try {
    const {
      fields,
      indices
    } = await indexPatterns.getFieldsForWildcard({
      pattern,
      metaFields: parsedMetaFields,
      type,
      rollupIndex,
      fieldCapsOptions: {
        allow_no_indices: allowNoIndex || false,
        includeUnmapped
      },
      indexFilter,
      ...(parsedFields.length > 0 ? {
        fields: parsedFields
      } : {})
    });
    const body = {
      fields,
      indices
    };
    return response.ok({
      body,
      headers: {
        'content-type': 'application/json'
      }
    });
  } catch (error) {
    var _error$output, _error$output2;
    if (typeof error === 'object' && !!(error !== null && error !== void 0 && error.isBoom) && !!(error !== null && error !== void 0 && (_error$output = error.output) !== null && _error$output !== void 0 && _error$output.payload) && typeof (error === null || error === void 0 ? void 0 : (_error$output2 = error.output) === null || _error$output2 === void 0 ? void 0 : _error$output2.payload) === 'object') {
      var _error$output3;
      const payload = error === null || error === void 0 ? void 0 : (_error$output3 = error.output) === null || _error$output3 === void 0 ? void 0 : _error$output3.payload;
      return response.notFound({
        body: {
          message: payload.message,
          attributes: payload
        }
      });
    } else {
      return response.notFound();
    }
  }
};
const registerFieldForWildcard = async (router, getStartServices, isRollupsEnabled) => {
  const configuredHandler = handler(isRollupsEnabled);

  // handler
  router.versioned.put({
    path: _constants2.FIELDS_FOR_WILDCARD_PATH,
    access
  }).addVersion({
    version: _constants.INITIAL_REST_VERSION_INTERNAL,
    validate
  }, configuredHandler);
  router.versioned.post({
    path: _constants2.FIELDS_FOR_WILDCARD_PATH,
    access
  }).addVersion({
    version: _constants.INITIAL_REST_VERSION_INTERNAL,
    validate
  }, configuredHandler);
  router.versioned.get({
    path: _constants2.FIELDS_FOR_WILDCARD_PATH,
    access
  }).addVersion({
    version: _constants.INITIAL_REST_VERSION_INTERNAL,
    validate: {
      request: {
        query: querySchema
      },
      response: validate.response
    }
  }, configuredHandler);
};
exports.registerFieldForWildcard = registerFieldForWildcard;