"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getServiceMapDependencyNodeInfo = getServiceMapDependencyNodeInfo;
var _common = require("@kbn/observability-plugin/common");
var _server = require("@kbn/observability-plugin/server");
var _document_type = require("../../../common/document_type");
var _apm = require("../../../common/es_fields/apm");
var _environment_query = require("../../../common/utils/environment_query");
var _get_bucket_size = require("../../../common/utils/get_bucket_size");
var _get_offset_in_ms = require("../../../common/utils/get_offset_in_ms");
var _calculate_throughput = require("../../lib/helpers/calculate_throughput");
var _get_is_using_service_destination_metrics = require("../../lib/helpers/spans/get_is_using_service_destination_metrics");
var _transaction_error_rate = require("../../lib/helpers/transaction_error_rate");
var _with_apm_span = require("../../utils/with_apm_span");
/*
 * 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.
 */

function getServiceMapDependencyNodeInfoForTimeRange({
  environment,
  dependencyName,
  apmEventClient,
  start,
  end,
  offset
}) {
  return (0, _with_apm_span.withApmSpan)('get_service_map_dependency_node_stats', async () => {
    var _response$aggregation, _response$aggregation2, _response$aggregation3, _response$aggregation4, _response$aggregation5, _response$aggregation6, _response$aggregation7;
    const {
      offsetInMs,
      startWithOffset,
      endWithOffset
    } = (0, _get_offset_in_ms.getOffsetInMs)({
      start,
      end,
      offset
    });
    const {
      intervalString
    } = (0, _get_bucket_size.getBucketSize)({
      start: startWithOffset,
      end: endWithOffset,
      numBuckets: 20
    });
    const subAggs = {
      latency_sum: {
        sum: {
          field: _apm.SPAN_DESTINATION_SERVICE_RESPONSE_TIME_SUM
        }
      },
      count: {
        sum: {
          field: _apm.SPAN_DESTINATION_SERVICE_RESPONSE_TIME_COUNT
        }
      },
      ...(0, _transaction_error_rate.getOutcomeAggregation)(_document_type.ApmDocumentType.ServiceDestinationMetric)
    };
    const response = await apmEventClient.search('get_service_map_dependency_node_stats', {
      apm: {
        events: [_common.ProcessorEvent.metric]
      },
      body: {
        track_total_hits: false,
        size: 0,
        query: {
          bool: {
            filter: [...(0, _get_is_using_service_destination_metrics.getDocumentTypeFilterForServiceDestinationStatistics)(true), {
              term: {
                [_apm.SPAN_DESTINATION_SERVICE_RESOURCE]: dependencyName
              }
            }, ...(0, _server.rangeQuery)(startWithOffset, endWithOffset), ...(0, _environment_query.environmentQuery)(environment)]
          }
        },
        aggs: {
          ...subAggs,
          timeseries: {
            date_histogram: {
              field: '@timestamp',
              fixed_interval: intervalString,
              min_doc_count: 0,
              extended_bounds: {
                min: startWithOffset,
                max: endWithOffset
              }
            },
            aggs: subAggs
          }
        }
      }
    });
    const count = (_response$aggregation = (_response$aggregation2 = response.aggregations) === null || _response$aggregation2 === void 0 ? void 0 : _response$aggregation2.count.value) !== null && _response$aggregation !== void 0 ? _response$aggregation : 0;
    const latencySum = (_response$aggregation3 = (_response$aggregation4 = response.aggregations) === null || _response$aggregation4 === void 0 ? void 0 : _response$aggregation4.latency_sum.value) !== null && _response$aggregation3 !== void 0 ? _response$aggregation3 : 0;
    const avgFailedTransactionsRate = response.aggregations ? (0, _transaction_error_rate.calculateFailedTransactionRate)(response.aggregations) : null;
    const latency = latencySum / count;
    const throughput = (0, _calculate_throughput.calculateThroughputWithRange)({
      start: startWithOffset,
      end: endWithOffset,
      value: count
    });
    if (count === 0) {
      return {
        failedTransactionsRate: undefined,
        transactionStats: {
          throughput: undefined,
          latency: undefined
        }
      };
    }
    return {
      failedTransactionsRate: {
        value: avgFailedTransactionsRate,
        timeseries: (_response$aggregation5 = response.aggregations) !== null && _response$aggregation5 !== void 0 && _response$aggregation5.timeseries ? (0, _transaction_error_rate.getFailedTransactionRateTimeSeries)(response.aggregations.timeseries.buckets).map(({
          x,
          y
        }) => ({
          x: x + offsetInMs,
          y
        })) : undefined
      },
      transactionStats: {
        throughput: {
          value: throughput,
          timeseries: (_response$aggregation6 = response.aggregations) === null || _response$aggregation6 === void 0 ? void 0 : _response$aggregation6.timeseries.buckets.map(bucket => {
            var _bucket$doc_count;
            return {
              x: bucket.key + offsetInMs,
              y: (0, _calculate_throughput.calculateThroughputWithRange)({
                start,
                end,
                value: (_bucket$doc_count = bucket.doc_count) !== null && _bucket$doc_count !== void 0 ? _bucket$doc_count : 0
              })
            };
          })
        },
        latency: {
          value: latency,
          timeseries: (_response$aggregation7 = response.aggregations) === null || _response$aggregation7 === void 0 ? void 0 : _response$aggregation7.timeseries.buckets.map(bucket => ({
            x: bucket.key + offsetInMs,
            y: bucket.latency_sum.value
          }))
        }
      }
    };
  });
}
async function getServiceMapDependencyNodeInfo({
  apmEventClient,
  dependencyName,
  start,
  end,
  environment,
  offset
}) {
  const commonProps = {
    environment,
    apmEventClient,
    dependencyName,
    start,
    end
  };
  const [currentPeriod, previousPeriod] = await Promise.all([getServiceMapDependencyNodeInfoForTimeRange(commonProps), offset ? getServiceMapDependencyNodeInfoForTimeRange({
    ...commonProps,
    offset
  }) : undefined]);
  return {
    currentPeriod,
    previousPeriod
  };
}