"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getClustersQuery = exports.getClustersFromAggs = exports.getClusters = void 0;
var _get_grouped_findings_evaluation = require("./get_grouped_findings_evaluation");
var _get_stats = require("./get_stats");
var _get_identifier_runtime_mapping = require("../../../common/runtime_mappings/get_identifier_runtime_mapping");
/*
 * 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 MAX_CLUSTERS = 500;
const getClustersQuery = (query, pitId, runtimeMappings) => ({
  size: 0,
  // creates the `asset_identifier` and `safe_posture_type` runtime fields,
  // `safe_posture_type` is used by the `query` to filter by posture type for older findings without this field
  runtime_mappings: {
    ...runtimeMappings,
    ...(0, _get_identifier_runtime_mapping.getIdentifierRuntimeMapping)()
  },
  query,
  aggs: {
    aggs_by_asset_identifier: {
      terms: {
        size: MAX_CLUSTERS,
        field: 'asset_identifier'
      },
      aggs: {
        latestFindingTopHit: {
          top_hits: {
            size: 1,
            sort: [{
              '@timestamp': {
                order: 'desc'
              }
            }]
          }
        },
        ..._get_grouped_findings_evaluation.failedFindingsAggQuery,
        ..._get_stats.findingsEvaluationAggsQuery
      }
    }
  },
  pit: {
    id: pitId
  }
});
exports.getClustersQuery = getClustersQuery;
const getClustersFromAggs = clusters => clusters.map(clusterBucket => {
  var _latestFindingHit$_so;
  const latestFindingHit = clusterBucket.latestFindingTopHit.hits.hits[0];
  if (!latestFindingHit._source) throw new Error('Missing findings top hits');
  const meta = {
    clusterId: clusterBucket.key,
    assetIdentifierId: clusterBucket.key,
    lastUpdate: latestFindingHit._source['@timestamp'],
    benchmark: latestFindingHit._source.rule.benchmark,
    cloud: latestFindingHit._source.cloud,
    // only available on CSPM findings
    cluster: (_latestFindingHit$_so = latestFindingHit._source.orchestrator) === null || _latestFindingHit$_so === void 0 ? void 0 : _latestFindingHit$_so.cluster // only available on KSPM findings
  };

  // get cluster's stats
  if (!clusterBucket.failed_findings || !clusterBucket.passed_findings) throw new Error('missing findings evaluations per cluster bucket');
  const stats = (0, _get_stats.getStatsFromFindingsEvaluationsAggs)(clusterBucket);

  // get cluster's resource types aggs
  const resourcesTypesAggs = clusterBucket.aggs_by_resource_type.buckets;
  if (!Array.isArray(resourcesTypesAggs)) throw new Error('missing aggs by resource type per cluster');
  const groupedFindingsEvaluation = (0, _get_grouped_findings_evaluation.getFailedFindingsFromAggs)(resourcesTypesAggs);
  return {
    meta,
    stats,
    groupedFindingsEvaluation
  };
});
exports.getClustersFromAggs = getClustersFromAggs;
const getClusters = async (esClient, query, pitId, runtimeMappings) => {
  var _queryResult$aggregat;
  const queryResult = await esClient.search(getClustersQuery(query, pitId, runtimeMappings));
  const clusters = (_queryResult$aggregat = queryResult.aggregations) === null || _queryResult$aggregat === void 0 ? void 0 : _queryResult$aggregat.aggs_by_asset_identifier.buckets;
  if (!Array.isArray(clusters)) throw new Error('missing aggs by cluster id');
  return getClustersFromAggs(clusters);
};
exports.getClusters = getClusters;