"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getEsaggs = getEsaggs;
exports.getFunctionDefinition = getFunctionDefinition;
var _lodash = require("lodash");
var _rxjs = require("rxjs");
var _operators = require("rxjs/operators");
var _expressions = require("../../../common/search/expressions");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /*
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * 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.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */
/**
 * Returns the expression function definition. Any stateful dependencies are accessed
 * at runtime via the `getStartDependencies` param, which provides the specific services
 * needed for this function to run.
 *
 * This function is an implementation detail of this module, and is exported separately
 * only for testing purposes.
 *
 * @param getStartDependencies - async function that resolves with EsaggsStartDependencies
 *
 * @internal
 */
function getFunctionDefinition({
  getStartDependencies
}) {
  return () => ({
    ...(0, _expressions.getEsaggsMeta)(),
    fn(input, args, {
      inspectorAdapters,
      abortSignal,
      getSearchSessionId,
      getExecutionContext,
      getSearchContext
    }) {
      return (0, _rxjs.defer)(async () => {
        var _args$aggs$map, _args$aggs;
        const {
          aggs,
          indexPatterns,
          searchSource,
          getNow
        } = await getStartDependencies();
        const indexPattern = await indexPatterns.create(args.index.value, true);
        const aggConfigs = aggs.createAggConfigs(indexPattern, (_args$aggs$map = (_args$aggs = args.aggs) === null || _args$aggs === void 0 ? void 0 : _args$aggs.map(agg => agg.value)) !== null && _args$aggs$map !== void 0 ? _args$aggs$map : [], {
          hierarchical: args.metricsAtAllLevels,
          partialRows: args.partialRows,
          probability: args.probability,
          samplerSeed: args.samplerSeed
        });
        const {
          handleEsaggsRequest
        } = await Promise.resolve().then(() => _interopRequireWildcard(require('../../../common/search/expressions')));
        return {
          aggConfigs,
          indexPattern,
          searchSource,
          getNow,
          handleEsaggsRequest
        };
      }).pipe((0, _operators.switchMap)(({
        aggConfigs,
        indexPattern,
        searchSource,
        getNow,
        handleEsaggsRequest
      }) => {
        const {
          disableWarningToasts
        } = getSearchContext();
        return handleEsaggsRequest({
          abortSignal,
          aggs: aggConfigs,
          filters: args.ignoreGlobalFilters ? undefined : (0, _lodash.get)(input, 'filters', undefined),
          indexPattern,
          inspectorAdapters,
          query: args.ignoreGlobalFilters ? undefined : (0, _lodash.get)(input, 'query', undefined),
          searchSessionId: getSearchSessionId(),
          searchSourceService: searchSource,
          timeFields: args.timeFields,
          timeRange: (0, _lodash.get)(input, 'timeRange', undefined),
          disableWarningToasts: disableWarningToasts || false,
          getNow,
          executionContext: getExecutionContext()
        });
      }));
    }
  });
}

/**
 * This is some glue code that takes in `core.getStartServices`, extracts the dependencies
 * needed for this function, and wraps them behind a `getStartDependencies` function that
 * is then called at runtime.
 *
 * We do this so that we can be explicit about exactly which dependencies the function
 * requires, without cluttering up the top-level `plugin.ts` with this logic. It also
 * makes testing the expression function a bit easier since `getStartDependencies` is
 * the only thing you should need to mock.
 *
 * @param getStartServices - core's StartServicesAccessor for this plugin
 *
 * @internal
 */
function getEsaggs({
  getStartServices
}) {
  return getFunctionDefinition({
    getStartDependencies: async () => {
      const [,, self] = await getStartServices();
      const {
        indexPatterns,
        search,
        nowProvider
      } = self;
      return {
        aggs: search.aggs,
        indexPatterns,
        searchSource: search.searchSource,
        getNow: () => nowProvider.get()
      };
    }
  });
}