"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.APMPlugin = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _server = require("@kbn/core/server");
var _lodash = require("lodash");
var _server2 = require("@kbn/rule-registry-plugin/server");
var _common = require("@kbn/alerting-plugin/common");
var _common2 = require("@kbn/observability-plugin/common");
var _ = require(".");
var _feature = require("./feature");
var _register_apm_rule_types = require("./routes/alerts/register_apm_rule_types");
var _register_fleet_policy_callbacks = require("./routes/fleet/register_fleet_policy_callbacks");
var _apm_telemetry = require("./lib/apm_telemetry");
var _get_internal_saved_objects_client = require("./lib/helpers/get_internal_saved_objects_client");
var _create_agent_config_index = require("./routes/settings/agent_configuration/create_agent_config_index");
var _create_custom_link_index = require("./routes/settings/custom_link/create_custom_link_index");
var _saved_objects = require("./saved_objects");
var _register_apm_server_routes = require("./routes/apm_routes/register_apm_server_routes");
var _get_global_apm_server_route_repository = require("./routes/apm_routes/get_global_apm_server_route_repository");
var _tutorial = require("./tutorial");
var _schedule_source_map_migration = require("./routes/source_maps/schedule_source_map_migration");
var _create_apm_source_map_index_template = require("./routes/source_maps/create_apm_source_map_index_template");
var _add_api_keys_to_policies_if_missing = require("./routes/fleet/api_keys/add_api_keys_to_policies_if_missing");
var _tutorials = require("../common/tutorial/tutorials");
var _data_view_constants = require("../common/data_view_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.
 */

class APMPlugin {
  constructor(initContext) {
    (0, _defineProperty2.default)(this, "currentConfig", void 0);
    (0, _defineProperty2.default)(this, "logger", void 0);
    this.initContext = initContext;
    this.initContext = initContext;
  }
  setup(core, plugins) {
    var _resourcePlugins$usag;
    this.logger = this.initContext.logger.get();
    const config$ = this.initContext.config.create();
    core.savedObjects.registerType(_saved_objects.apmTelemetry);
    core.savedObjects.registerType(_saved_objects.apmServerSettings);
    core.savedObjects.registerType(_saved_objects.apmServiceGroups);
    core.savedObjects.registerType(_saved_objects.apmCustomDashboards);
    const currentConfig = this.initContext.config.get();
    this.currentConfig = currentConfig;
    if (plugins.taskManager && plugins.usageCollection && currentConfig.telemetryCollectionEnabled) {
      (0, _apm_telemetry.createApmTelemetry)({
        core,
        getApmIndices: plugins.apmDataAccess.getApmIndices,
        usageCollector: plugins.usageCollection,
        taskManager: plugins.taskManager,
        logger: this.logger,
        kibanaVersion: this.initContext.env.packageInfo.version,
        isProd: this.initContext.env.mode.prod
      });
    }
    plugins.features.registerKibanaFeature(_feature.APM_FEATURE);
    (0, _feature.registerFeaturesUsage)({
      licensingPlugin: plugins.licensing
    });
    const getCoreStart = () => core.getStartServices().then(([coreStart]) => coreStart);
    const getPluginStart = () => core.getStartServices().then(([coreStart, pluginStart]) => pluginStart);
    const {
      ruleDataService
    } = plugins.ruleRegistry;
    const ruleDataClient = ruleDataService.initializeIndex({
      feature: _.APM_SERVER_FEATURE_ID,
      registrationContext: _register_apm_rule_types.APM_RULE_TYPE_ALERT_CONTEXT,
      dataset: _server2.Dataset.alerts,
      componentTemplateRefs: [],
      componentTemplates: [{
        name: 'mappings',
        mappings: (0, _common.mappingFromFieldMap)(_register_apm_rule_types.apmRuleTypeAlertFieldMap, 'strict')
      }]
    });

    // ensure that the APM data view is globally available
    getCoreStart().then(async coreStart => {
      const soClient = new _server.SavedObjectsClient(coreStart.savedObjects.createInternalRepository());
      await soClient.updateObjectsSpaces([{
        id: _data_view_constants.APM_STATIC_DATA_VIEW_ID,
        type: 'index-pattern'
      }], ['*'], []);
    }).catch(e => {
      var _this$logger;
      (_this$logger = this.logger) === null || _this$logger === void 0 ? void 0 : _this$logger.error('Failed to make APM data view available globally', e);
    });
    const resourcePlugins = (0, _lodash.mapValues)(plugins, (value, key) => {
      return {
        setup: value,
        start: () => core.getStartServices().then(services => {
          const [, pluginsStartContracts] = services;
          return pluginsStartContracts[key];
        })
      };
    });
    const apmIndicesPromise = (async () => {
      const coreStart = await getCoreStart();
      const soClient = await (0, _get_internal_saved_objects_client.getInternalSavedObjectsClient)(coreStart);
      const {
        getApmIndices
      } = plugins.apmDataAccess;
      return getApmIndices(soClient);
    })();

    // This if else block will go away in favour of removing Home Tutorial Integration
    // Ideally we will directly register a custom integration and pass the configs
    // for cloud, onPrem and Serverless so that the actual component can take
    // care of rendering
    if (currentConfig.serverlessOnboarding && plugins.customIntegrations) {
      var _plugins$customIntegr;
      (_plugins$customIntegr = plugins.customIntegrations) === null || _plugins$customIntegr === void 0 ? void 0 : _plugins$customIntegr.registerCustomIntegration(_tutorials.apmTutorialCustomIntegration);
    } else {
      apmIndicesPromise.then(apmIndices => {
        var _plugins$home;
        (_plugins$home = plugins.home) === null || _plugins$home === void 0 ? void 0 : _plugins$home.tutorials.registerTutorial((0, _tutorial.tutorialProvider)({
          apmConfig: currentConfig,
          apmIndices,
          cloud: plugins.cloud,
          isFleetPluginEnabled: !(0, _lodash.isEmpty)(resourcePlugins.fleet)
        }));
      });
    }
    const telemetryUsageCounter = (_resourcePlugins$usag = resourcePlugins.usageCollection) === null || _resourcePlugins$usag === void 0 ? void 0 : _resourcePlugins$usag.setup.createUsageCounter(_.APM_SERVER_FEATURE_ID);
    (0, _register_apm_server_routes.registerRoutes)({
      core: {
        setup: core,
        start: getCoreStart
      },
      logger: this.logger,
      config: currentConfig,
      featureFlags: currentConfig.featureFlags,
      repository: (0, _get_global_apm_server_route_repository.getGlobalApmServerRouteRepository)(),
      ruleDataClient,
      plugins: resourcePlugins,
      telemetryUsageCounter,
      kibanaVersion: this.initContext.env.packageInfo.version
    });
    const {
      getApmIndices
    } = plugins.apmDataAccess;
    if (plugins.alerting) {
      (0, _register_apm_rule_types.registerApmRuleTypes)({
        getApmIndices,
        alerting: plugins.alerting,
        basePath: core.http.basePath,
        apmConfig: currentConfig,
        logger: this.logger.get('rule'),
        ml: plugins.ml,
        observability: plugins.observability,
        ruleDataClient,
        alertsLocator: plugins.share.url.locators.get(_common2.alertsLocatorID)
      });
    }
    (0, _register_fleet_policy_callbacks.registerFleetPolicyCallbacks)({
      logger: this.logger,
      coreStartPromise: getCoreStart(),
      plugins: resourcePlugins
    }).catch(e => {
      var _this$logger2, _this$logger3;
      (_this$logger2 = this.logger) === null || _this$logger2 === void 0 ? void 0 : _this$logger2.error('Failed to register APM Fleet policy callbacks');
      (_this$logger3 = this.logger) === null || _this$logger3 === void 0 ? void 0 : _this$logger3.error(e);
    });

    // This will add an API key to all existing APM package policies
    (0, _add_api_keys_to_policies_if_missing.addApiKeysToEveryPackagePolicyIfMissing)({
      coreStartPromise: getCoreStart(),
      pluginStartPromise: getPluginStart(),
      logger: this.logger
    }).catch(e => {
      var _this$logger4, _this$logger5;
      (_this$logger4 = this.logger) === null || _this$logger4 === void 0 ? void 0 : _this$logger4.error('Failed to add API keys to APM package policies');
      (_this$logger5 = this.logger) === null || _this$logger5 === void 0 ? void 0 : _this$logger5.error(e);
    });
    const taskManager = plugins.taskManager;

    // create source map index and run migrations
    (0, _schedule_source_map_migration.scheduleSourceMapMigration)({
      coreStartPromise: getCoreStart(),
      pluginStartPromise: getPluginStart(),
      taskManager,
      logger: this.logger
    }).catch(e => {
      var _this$logger6, _this$logger7;
      (_this$logger6 = this.logger) === null || _this$logger6 === void 0 ? void 0 : _this$logger6.error('Failed to schedule APM source map migration');
      (_this$logger7 = this.logger) === null || _this$logger7 === void 0 ? void 0 : _this$logger7.error(e);
    });
    return {
      config$
    };
  }
  start(core, plugins) {
    if (this.currentConfig == null || this.logger == null) {
      throw new Error('APMPlugin needs to be setup before calling start()');
    }
    const logger = this.logger;
    const client = core.elasticsearch.client.asInternalUser;

    // create .apm-agent-configuration index without blocking start lifecycle
    (0, _create_agent_config_index.createApmAgentConfigurationIndex)({
      client,
      logger
    }).catch(e => {
      logger.error('Failed to create .apm-agent-configuration index');
      logger.error(e);
    });

    // create .apm-custom-link index without blocking start lifecycle
    (0, _create_custom_link_index.createApmCustomLinkIndex)({
      client,
      logger
    }).catch(e => {
      logger.error('Failed to create .apm-custom-link index');
      logger.error(e);
    });

    // create .apm-source-map index without blocking start lifecycle
    (0, _create_apm_source_map_index_template.createApmSourceMapIndexTemplate)({
      client,
      logger
    }).catch(e => {
      logger.error('Failed to create apm-source-map index template');
      logger.error(e);
    });
  }
  stop() {}
}
exports.APMPlugin = APMPlugin;