"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getResourcesStats = void 0;
var _get_identifier_runtime_mapping = require("../../../../common/runtime_mappings/get_identifier_runtime_mapping");
var _constants = require("../../../../common/constants");
/*
 * 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 getResourcesStatsQuery = index => ({
  index,
  query: {
    match_all: {}
  },
  runtime_mappings: (0, _get_identifier_runtime_mapping.getIdentifierRuntimeMapping)(),
  aggs: {
    accounts: {
      terms: {
        field: 'asset_identifier',
        order: {
          _count: 'desc'
        },
        size: 100
      },
      aggs: {
        resource_type: {
          terms: {
            field: 'resource.type',
            order: {
              _count: 'desc'
            },
            size: 100
          },
          aggs: {
            resource_sub_type: {
              terms: {
                field: 'resource.sub_type',
                order: {
                  _count: 'desc'
                },
                size: 100
              },
              aggs: {
                evaluation: {
                  terms: {
                    field: 'result.evaluation',
                    order: {
                      _count: 'desc'
                    },
                    size: 5,
                    shard_size: 25
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  size: 0,
  _source: false
});
const getEvaluationStats = resourceSubType => {
  var _resourceSubType$eval, _resourceSubType$eval2;
  const passed = ((_resourceSubType$eval = resourceSubType.evaluation.buckets.find(evaluation => evaluation.key === 'passed')) === null || _resourceSubType$eval === void 0 ? void 0 : _resourceSubType$eval.doc_count) || 0;
  const failed = ((_resourceSubType$eval2 = resourceSubType.evaluation.buckets.find(evaluation => evaluation.key === 'failed')) === null || _resourceSubType$eval2 === void 0 ? void 0 : _resourceSubType$eval2.doc_count) || 0;
  return {
    passed_findings_count: passed,
    failed_findings_count: failed
  };
};
const getCspmResourcesStats = (aggregatedResourcesStats, logger) => {
  const accounts = aggregatedResourcesStats.accounts.buckets;
  const resourcesStats = accounts.map(account => {
    const accountId = account.key;
    return account.resource_type.buckets.map(resourceType => {
      return resourceType.resource_sub_type.buckets.map(resourceSubType => {
        const evaluation = getEvaluationStats(resourceSubType);
        return {
          account_id: accountId,
          resource_type: resourceType.key,
          resource_type_doc_count: resourceType.doc_count,
          resource_sub_type: resourceSubType.key,
          resource_sub_type_doc_count: resourceSubType.doc_count,
          ...evaluation
        };
      });
    });
  });
  logger.info('CSPM telemetry: resources stats was sent');
  return resourcesStats.flat(2);
};
const getResourcesStats = async (esClient, logger) => {
  try {
    const isIndexExists = await esClient.indices.exists({
      index: _constants.LATEST_FINDINGS_INDEX_DEFAULT_NS
    });
    if (isIndexExists) {
      const resourcesStatsResponse = await esClient.search(getResourcesStatsQuery(_constants.LATEST_FINDINGS_INDEX_DEFAULT_NS));
      const cspmResourcesStats = resourcesStatsResponse.aggregations ? getCspmResourcesStats(resourcesStatsResponse.aggregations, logger) : [];
      return cspmResourcesStats;
    }
    return [];
  } catch (e) {
    logger.error(`Failed to get resources stats ${e}`);
    return [];
  }
};
exports.getResourcesStats = getResourcesStats;