"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.APMEventClient = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _common = require("@kbn/observability-plugin/common");
var _server = require("@kbn/observability-plugin/server");
var _lodash = require("lodash");
var _with_apm_span = require("../../../../utils/with_apm_span");
var _call_async_with_debug = require("../call_async_with_debug");
var _cancel_es_request_on_abort = require("../cancel_es_request_on_abort");
var _get_request_base = require("./get_request_base");
/*
 * 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.
 */

// These keys shoul all be `ProcessorEvent.x`, but until TypeScript 4.2 we're inlining them here.
// See https://github.com/microsoft/TypeScript/issues/37888

class APMEventClient {
  constructor(config) {
    (0, _defineProperty2.default)(this, "esClient", void 0);
    (0, _defineProperty2.default)(this, "debug", void 0);
    (0, _defineProperty2.default)(this, "request", void 0);
    (0, _defineProperty2.default)(this, "indices", void 0);
    (0, _defineProperty2.default)(this, "includeFrozen", void 0);
    (0, _defineProperty2.default)(this, "forceSyntheticSource", void 0);
    this.esClient = config.esClient;
    this.debug = config.debug;
    this.request = config.request;
    this.indices = config.indices;
    this.includeFrozen = config.options.includeFrozen;
    this.forceSyntheticSource = config.options.forceSyntheticSource;
  }
  callAsyncWithDebug({
    requestType,
    params,
    cb,
    operationName
  }) {
    return (0, _call_async_with_debug.callAsyncWithDebug)({
      getDebugMessage: () => ({
        body: (0, _call_async_with_debug.getDebugBody)({
          params,
          requestType,
          operationName
        }),
        title: (0, _call_async_with_debug.getDebugTitle)(this.request)
      }),
      isCalledWithInternalUser: false,
      debug: this.debug,
      request: this.request,
      operationName,
      requestParams: params,
      cb: () => {
        const controller = new AbortController();
        const promise = (0, _with_apm_span.withApmSpan)(operationName, () => {
          return (0, _cancel_es_request_on_abort.cancelEsRequestOnAbort)(cb({
            signal: controller.signal,
            meta: true
          }), this.request, controller);
        });
        return (0, _server.unwrapEsResponse)(promise);
      }
    });
  }
  async search(operationName, params) {
    const {
      events,
      index,
      filters
    } = (0, _get_request_base.getRequestBase)({
      apm: params.apm,
      indices: this.indices
    });
    const forceSyntheticSourceForThisRequest = this.forceSyntheticSource && events.includes(_common.ProcessorEvent.metric);
    const searchParams = {
      ...(0, _lodash.omit)(params, 'apm', 'body'),
      index,
      body: {
        ...params.body,
        query: {
          bool: {
            filter: filters,
            must: (0, _lodash.compact)([params.body.query])
          }
        }
      },
      ...(this.includeFrozen ? {
        ignore_throttled: false
      } : {}),
      ignore_unavailable: true,
      preference: 'any',
      expand_wildcards: ['open', 'hidden'],
      ...(forceSyntheticSourceForThisRequest ? {
        force_synthetic_source: true
      } : {})
    };
    return this.callAsyncWithDebug({
      cb: opts => this.esClient.search(searchParams, opts),
      operationName,
      params: searchParams,
      requestType: 'search'
    });
  }
  async msearch(operationName, ...allParams) {
    const searches = allParams.map(params => {
      const {
        index,
        filters
      } = (0, _get_request_base.getRequestBase)({
        apm: params.apm,
        indices: this.indices
      });
      const searchParams = [{
        index,
        preference: 'any',
        ...(this.includeFrozen ? {
          ignore_throttled: false
        } : {}),
        ignore_unavailable: true,
        expand_wildcards: ['open', 'hidden']
      }, {
        ...(0, _lodash.omit)(params, 'apm', 'body'),
        ...params.body,
        query: {
          bool: {
            filter: (0, _lodash.compact)([params.body.query, ...filters])
          }
        }
      }];
      return searchParams;
    }).flat();
    return this.callAsyncWithDebug({
      cb: opts => this.esClient.msearch({
        searches
      }, opts),
      operationName,
      params: searches,
      requestType: 'msearch'
    });
  }
  async eqlSearch(operationName, params) {
    const index = (0, _get_request_base.processorEventsToIndex)(params.apm.events, this.indices);
    const requestParams = {
      ...(0, _lodash.omit)(params, 'apm'),
      index
    };
    return this.callAsyncWithDebug({
      operationName,
      requestType: 'eql_search',
      params: requestParams,
      cb: opts => this.esClient.eql.search(requestParams, opts)
    });
  }
  async fieldCaps(operationName, params) {
    const index = (0, _get_request_base.processorEventsToIndex)(params.apm.events, this.indices);
    const requestParams = {
      ...(0, _lodash.omit)(params, 'apm'),
      index
    };
    return this.callAsyncWithDebug({
      operationName,
      requestType: '_field_caps',
      params: requestParams,
      cb: opts => this.esClient.fieldCaps(requestParams, opts)
    });
  }
  async termsEnum(operationName, params) {
    const index = (0, _get_request_base.processorEventsToIndex)(params.apm.events, this.indices);
    const requestParams = {
      ...(0, _lodash.omit)(params, 'apm'),
      index: index.join(',')
    };
    return this.callAsyncWithDebug({
      operationName,
      requestType: '_terms_enum',
      params: requestParams,
      cb: opts => this.esClient.termsEnum(requestParams, opts)
    });
  }
}
exports.APMEventClient = APMEventClient;