"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getDocumentSources = getDocumentSources;
var _server = require("@kbn/observability-plugin/server");
var _document_type = require("../../../common/document_type");
var _rollup = require("../../../common/rollup");
var _document_type2 = require("./create_es_client/document_type");
var _apm = require("../../../common/es_fields/apm");
/*
 * 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 getRequest = ({
  documentType,
  rollupInterval,
  filters
}) => {
  const searchParams = {
    apm: {
      sources: [{
        documentType,
        rollupInterval
      }]
    },
    body: {
      track_total_hits: 1,
      size: 0,
      terminate_after: 1
    }
  };
  return {
    ...searchParams,
    body: {
      ...searchParams.body,
      query: {
        bool: {
          filter: filters
        }
      }
    }
  };
};
async function getDocumentSources({
  apmEventClient,
  start,
  end,
  kuery,
  enableServiceTransactionMetrics,
  enableContinuousRollups
}) {
  const currentRange = (0, _server.rangeQuery)(start, end);
  const diff = end - start;
  const kql = (0, _server.kqlQuery)(kuery);
  const beforeRange = (0, _server.rangeQuery)(start - diff, end - diff);
  const sourcesToCheck = [...(enableServiceTransactionMetrics ? [_document_type.ApmDocumentType.ServiceTransactionMetric] : []), _document_type.ApmDocumentType.TransactionMetric].flatMap(documentType => {
    const docTypeConfig = (0, _document_type2.getConfigForDocumentType)(documentType);
    return (enableContinuousRollups ? docTypeConfig.rollupIntervals : [_rollup.RollupInterval.OneMinute]).flatMap(rollupInterval => {
      return {
        documentType,
        rollupInterval,
        meta: {
          checkSummaryFieldExists: false
        },
        before: getRequest({
          documentType,
          rollupInterval,
          filters: [...kql, ...beforeRange]
        }),
        current: getRequest({
          documentType,
          rollupInterval,
          filters: [...kql, ...currentRange]
        })
      };
    });
  });
  const sourcesToCheckWithSummary = [_document_type.ApmDocumentType.TransactionMetric].flatMap(documentType => {
    const docTypeConfig = (0, _document_type2.getConfigForDocumentType)(documentType);
    return (enableContinuousRollups ? docTypeConfig.rollupIntervals : [_rollup.RollupInterval.OneMinute]).flatMap(rollupInterval => {
      const summaryExistsFilter = {
        bool: {
          filter: [{
            exists: {
              field: _apm.TRANSACTION_DURATION_SUMMARY
            }
          }]
        }
      };
      return {
        documentType,
        rollupInterval,
        meta: {
          checkSummaryFieldExists: true
        },
        before: getRequest({
          documentType,
          rollupInterval,
          filters: [...kql, ...beforeRange, summaryExistsFilter]
        }),
        current: getRequest({
          documentType,
          rollupInterval,
          filters: [...kql, ...currentRange, summaryExistsFilter]
        })
      };
    });
  });
  const allSourcesToCheck = [...sourcesToCheck, ...sourcesToCheckWithSummary];
  const allSearches = allSourcesToCheck.flatMap(({
    before,
    current
  }) => [before, current]);
  const allResponses = (await apmEventClient.msearch('get_document_availability', ...allSearches)).responses;
  const checkedSources = allSourcesToCheck.map((source, index) => {
    const {
      documentType,
      rollupInterval
    } = source;
    const responseBefore = allResponses[index * 2];
    const responseAfter = allResponses[index * 2 + 1];
    const hasDocBefore = responseBefore.hits.total.value > 0;
    const hasDocAfter = responseAfter.hits.total.value > 0;
    return {
      documentType,
      rollupInterval,
      hasDocBefore,
      hasDocAfter,
      checkSummaryFieldExists: source.meta.checkSummaryFieldExists
    };
  });
  const hasAnySourceDocBefore = checkedSources.some(source => source.hasDocBefore);
  const sourcesWithHasDocs = checkedSources.map(checkedSource => {
    const {
      documentType,
      hasDocAfter,
      hasDocBefore,
      rollupInterval,
      checkSummaryFieldExists
    } = checkedSource;
    const hasDocBeforeOrAfter = hasDocBefore || hasDocAfter;
    // If there is any data before, we require that data is available before
    // this time range to mark this source as available. If we don't do that,
    // users that upgrade to a version that starts generating service tx metrics
    // will see a mostly empty screen for a while after upgrading.
    // If we only check before, users with a new deployment will use raw transaction
    // events.
    const hasDocs = hasAnySourceDocBefore ? hasDocBefore : hasDocBeforeOrAfter;
    return {
      documentType,
      rollupInterval,
      checkSummaryFieldExists,
      hasDocs
    };
  });
  const sources = sourcesWithHasDocs.filter(source => !source.checkSummaryFieldExists).map(checkedSource => {
    var _sourcesWithHasDocs$f;
    const {
      documentType,
      hasDocs,
      rollupInterval
    } = checkedSource;
    return {
      documentType,
      rollupInterval,
      hasDocs,
      hasDurationSummaryField: documentType === _document_type.ApmDocumentType.ServiceTransactionMetric || Boolean((_sourcesWithHasDocs$f = sourcesWithHasDocs.find(eSource => {
        return eSource.documentType === documentType && eSource.rollupInterval === rollupInterval && eSource.checkSummaryFieldExists;
      })) === null || _sourcesWithHasDocs$f === void 0 ? void 0 : _sourcesWithHasDocs$f.hasDocs)
    };
  });
  return sources.concat({
    documentType: _document_type.ApmDocumentType.TransactionEvent,
    rollupInterval: _rollup.RollupInterval.None,
    hasDocs: true,
    hasDurationSummaryField: false
  });
}