"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.enhancedEsSearchStrategyProvider = void 0;
var _operators = require("rxjs/operators");
var _rxjs = require("rxjs");
var _server = require("@kbn/kibana-utils-plugin/server");
var _common = require("../../../../common");
var _request_utils = require("./request_utils");
var _response_utils = require("./response_utils");
var _search = require("../../collectors/search");
var _es_search = require("../es_search");
/*
 * 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.
 */

const enhancedEsSearchStrategyProvider = (legacyConfig$, searchConfig, logger, usage, useInternalUser = false) => {
  async function cancelAsyncSearch(id, esClient) {
    try {
      const client = useInternalUser ? esClient.asInternalUser : esClient.asCurrentUser;
      await client.asyncSearch.delete({
        id
      });
    } catch (e) {
      throw (0, _server.getKbnServerError)(e);
    }
  }
  function asyncSearch({
    id,
    ...request
  }, options, {
    esClient,
    uiSettingsClient
  }) {
    const client = useInternalUser ? esClient.asInternalUser : esClient.asCurrentUser;
    const search = async () => {
      const params = id ? (0, _request_utils.getDefaultAsyncGetParams)(searchConfig, options) : {
        ...(await (0, _request_utils.getDefaultAsyncSubmitParams)(uiSettingsClient, searchConfig, options)),
        ...request.params
      };
      const {
        body,
        headers
      } = id ? await client.asyncSearch.get({
        ...params,
        id
      }, {
        ...options.transport,
        signal: options.abortSignal,
        meta: true
      }) : await client.asyncSearch.submit(params, {
        ...options.transport,
        signal: options.abortSignal,
        meta: true
      });
      const response = (0, _es_search.shimHitsTotal)(body.response, options);
      return (0, _response_utils.toAsyncKibanaSearchResponse)({
        ...body,
        response
      }, headers === null || headers === void 0 ? void 0 : headers.warning);
    };
    const cancel = async () => {
      if (id) {
        await cancelAsyncSearch(id, esClient);
      }
    };
    return (0, _common.pollSearch)(search, cancel, {
      pollInterval: searchConfig.asyncSearch.pollInterval,
      ...options
    }).pipe((0, _operators.tap)(response => id = response.id), (0, _operators.tap)((0, _search.searchUsageObserver)(logger, usage)), (0, _operators.catchError)(e => {
      throw (0, _server.getKbnServerError)(e);
    }));
  }
  async function rollupSearch(request, options, {
    esClient,
    uiSettingsClient
  }) {
    const client = useInternalUser ? esClient.asInternalUser : esClient.asCurrentUser;
    const legacyConfig = await (0, _rxjs.firstValueFrom)(legacyConfig$);
    const {
      body,
      index,
      ...params
    } = request.params;
    const method = 'POST';
    const path = encodeURI(`/${index}/_rollup_search`);
    const querystring = {
      ...(0, _es_search.getShardTimeout)(legacyConfig),
      ...(await (0, _request_utils.getIgnoreThrottled)(uiSettingsClient)),
      ...(await (0, _es_search.getDefaultSearchParams)(uiSettingsClient)),
      ...params
    };
    try {
      const esResponse = await client.transport.request({
        method,
        path,
        body,
        querystring
      }, {
        signal: options === null || options === void 0 ? void 0 : options.abortSignal,
        meta: true
      });
      const response = esResponse.body;
      return {
        rawResponse: (0, _es_search.shimHitsTotal)(response, options),
        ...(0, _es_search.getTotalLoaded)(response)
      };
    } catch (e) {
      throw (0, _server.getKbnServerError)(e);
    }
  }
  return {
    /**
     * @param request
     * @param options
     * @param deps `SearchStrategyDependencies`
     * @returns `Observable<IEsSearchResponse<any>>`
     * @throws `KbnServerError`
     */
    search: (request, options, deps) => {
      logger.debug(`search ${JSON.stringify(request.params) || request.id}`);
      if (request.indexType && request.indexType !== 'rollup') {
        throw new _server.KbnServerError('Unknown indexType', 400);
      }
      if (request.indexType === undefined || !deps.rollupsEnabled) {
        return asyncSearch(request, options, deps);
      } else {
        return (0, _rxjs.from)(rollupSearch(request, options, deps));
      }
    },
    /**
     * @param id async search ID to cancel, as returned from _async_search API
     * @param options
     * @param deps `SearchStrategyDependencies`
     * @returns `Promise<void>`
     * @throws `KbnServerError`
     */
    cancel: async (id, options, {
      esClient
    }) => {
      logger.debug(`cancel ${id}`);
      await cancelAsyncSearch(id, esClient);
    },
    /**
     *
     * @param id async search ID to extend, as returned from _async_search API
     * @param keepAlive
     * @param options
     * @param deps `SearchStrategyDependencies`
     * @returns `Promise<void>`
     * @throws `KbnServerError`
     */
    extend: async (id, keepAlive, options, {
      esClient
    }) => {
      logger.debug(`extend ${id} by ${keepAlive}`);
      try {
        const client = useInternalUser ? esClient.asInternalUser : esClient.asCurrentUser;
        await client.asyncSearch.get({
          id,
          keep_alive: keepAlive
        });
      } catch (e) {
        throw (0, _server.getKbnServerError)(e);
      }
    }
  };
};
exports.enhancedEsSearchStrategyProvider = enhancedEsSearchStrategyProvider;