"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getServiceMetadataDetails = getServiceMetadataDetails;
var _server = require("@kbn/observability-plugin/server");
var _common = require("@kbn/observability-plugin/common");
var _environment_query = require("../../../common/utils/environment_query");
var _apm = require("../../../common/es_fields/apm");
var _get_service_metadata_icons = require("./get_service_metadata_icons");
var _agent_name = require("../../../common/agent_name");
/*
 * 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.
 */

async function getServiceMetadataDetails({
  serviceName,
  environment,
  apmEventClient,
  start,
  end
}) {
  var _response$aggregation, _service$framework, _response$aggregation2, _host$os, _response$aggregation3, _response$aggregation4, _response$aggregation5, _cloud$service, _response$aggregation6, _response$aggregation7, _cloud$project, _cloud$service2, _response$aggregation8, _response$aggregation9, _response$aggregation10;
  const filter = [{
    term: {
      [_apm.SERVICE_NAME]: serviceName
    }
  }, ...(0, _environment_query.environmentQuery)(environment), ...(0, _server.rangeQuery)(start, end)];
  const params = {
    apm: {
      events: [_common.ProcessorEvent.transaction, _common.ProcessorEvent.error, _common.ProcessorEvent.metric]
    },
    sort: [{
      _score: {
        order: 'desc'
      }
    }, {
      '@timestamp': {
        order: 'desc'
      }
    }],
    body: {
      track_total_hits: 1,
      size: 1,
      _source: [_apm.SERVICE, _apm.AGENT, _apm.HOST, _apm.CONTAINER, _apm.KUBERNETES, _apm.CLOUD, _apm.LABEL_TELEMETRY_AUTO_VERSION],
      query: {
        bool: {
          filter,
          should: _get_service_metadata_icons.should
        }
      },
      aggs: {
        serviceVersions: {
          terms: {
            field: _apm.SERVICE_VERSION,
            size: 10,
            order: {
              _key: 'desc'
            }
          }
        },
        availabilityZones: {
          terms: {
            field: _apm.CLOUD_AVAILABILITY_ZONE,
            size: 10
          }
        },
        containerIds: {
          terms: {
            field: _apm.CONTAINER_ID,
            size: 10
          }
        },
        regions: {
          terms: {
            field: _apm.CLOUD_REGION,
            size: 10
          }
        },
        cloudServices: {
          terms: {
            field: _apm.CLOUD_SERVICE_NAME,
            size: 1
          }
        },
        machineTypes: {
          terms: {
            field: _apm.CLOUD_MACHINE_TYPE,
            size: 10
          }
        },
        faasTriggerTypes: {
          terms: {
            field: _apm.FAAS_TRIGGER_TYPE,
            size: 10
          }
        },
        faasFunctionNames: {
          terms: {
            field: _apm.FAAS_ID,
            size: 10
          }
        },
        totalNumberInstances: {
          cardinality: {
            field: _apm.SERVICE_NODE_NAME
          }
        }
      }
    }
  };
  const response = await apmEventClient.search('get_service_metadata_details', params);
  if (response.hits.total.value === 0) {
    return {
      service: undefined,
      container: undefined,
      cloud: undefined
    };
  }
  const {
    service,
    agent,
    host,
    kubernetes,
    container,
    cloud,
    labels
  } = response.hits.hits[0]._source;
  const serviceMetadataDetails = {
    versions: (_response$aggregation = response.aggregations) === null || _response$aggregation === void 0 ? void 0 : _response$aggregation.serviceVersions.buckets.map(bucket => bucket.key),
    runtime: service.runtime,
    framework: (_service$framework = service.framework) === null || _service$framework === void 0 ? void 0 : _service$framework.name,
    agent
  };
  const otelDetails = !!(agent !== null && agent !== void 0 && agent.name) && (0, _agent_name.isOpenTelemetryAgentName)(agent.name) ? {
    language: agent.name.startsWith('opentelemetry') ? agent.name.replace(/^opentelemetry\//, '') : undefined,
    sdkVersion: agent === null || agent === void 0 ? void 0 : agent.version,
    autoVersion: labels === null || labels === void 0 ? void 0 : labels.telemetry_auto_version
  } : undefined;
  const totalNumberInstances = (_response$aggregation2 = response.aggregations) === null || _response$aggregation2 === void 0 ? void 0 : _response$aggregation2.totalNumberInstances.value;
  const containerDetails = host || container || totalNumberInstances || kubernetes ? {
    type: !!kubernetes ? 'Kubernetes' : 'Docker',
    os: host === null || host === void 0 ? void 0 : (_host$os = host.os) === null || _host$os === void 0 ? void 0 : _host$os.platform,
    totalNumberInstances,
    ids: (_response$aggregation3 = response.aggregations) === null || _response$aggregation3 === void 0 ? void 0 : _response$aggregation3.containerIds.buckets.map(bucket => bucket.key)
  } : undefined;
  const serverlessDetails = !!((_response$aggregation4 = response.aggregations) !== null && _response$aggregation4 !== void 0 && (_response$aggregation5 = _response$aggregation4.faasTriggerTypes) !== null && _response$aggregation5 !== void 0 && _response$aggregation5.buckets.length) && cloud ? {
    type: (_cloud$service = cloud.service) === null || _cloud$service === void 0 ? void 0 : _cloud$service.name,
    functionNames: (_response$aggregation6 = response.aggregations) === null || _response$aggregation6 === void 0 ? void 0 : _response$aggregation6.faasFunctionNames.buckets.map(bucket => getLambdaFunctionNameFromARN(bucket.key)).filter(name => name),
    faasTriggerTypes: (_response$aggregation7 = response.aggregations) === null || _response$aggregation7 === void 0 ? void 0 : _response$aggregation7.faasTriggerTypes.buckets.map(bucket => bucket.key),
    hostArchitecture: host === null || host === void 0 ? void 0 : host.architecture
  } : undefined;
  const cloudDetails = cloud ? {
    provider: cloud.provider,
    projectName: (_cloud$project = cloud.project) === null || _cloud$project === void 0 ? void 0 : _cloud$project.name,
    serviceName: (_cloud$service2 = cloud.service) === null || _cloud$service2 === void 0 ? void 0 : _cloud$service2.name,
    availabilityZones: (_response$aggregation8 = response.aggregations) === null || _response$aggregation8 === void 0 ? void 0 : _response$aggregation8.availabilityZones.buckets.map(bucket => bucket.key),
    regions: (_response$aggregation9 = response.aggregations) === null || _response$aggregation9 === void 0 ? void 0 : _response$aggregation9.regions.buckets.map(bucket => bucket.key),
    machineTypes: (_response$aggregation10 = response.aggregations) === null || _response$aggregation10 === void 0 ? void 0 : _response$aggregation10.machineTypes.buckets.map(bucket => bucket.key)
  } : undefined;
  return {
    service: serviceMetadataDetails,
    opentelemetry: otelDetails,
    container: containerDetails,
    serverless: serverlessDetails,
    cloud: cloudDetails
  };
}
function getLambdaFunctionNameFromARN(arn) {
  // Lambda function ARN example: arn:aws:lambda:us-west-2:123456789012:function:my-function
  return arn.split(':')[6] || '';
}