"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.createRuleSavedObject = createRuleSavedObject;
var _apmUtils = require("@kbn/apm-utils");
var _bulk_mark_api_keys_for_invalidation = require("../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation");
var _audit_events = require("../common/audit_events");
var _update_meta = require("./update_meta");
var _schedule_task = require("./schedule_task");
var _get_alert_from_raw = require("./get_alert_from_raw");
var _rule = require("../../data/rule");
/*
 * 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.
 */

// TODO (http-versioning): Remove this overload when we convert all types,
// this exists for easy interop until then.

async function createRuleSavedObject(context, params) {
  var _context$auditLogger;
  const {
    intervalInMs,
    rawRule,
    references,
    ruleId,
    options,
    returnRuleAttributes
  } = params;
  (_context$auditLogger = context.auditLogger) === null || _context$auditLogger === void 0 ? void 0 : _context$auditLogger.log((0, _audit_events.ruleAuditEvent)({
    action: _audit_events.RuleAuditAction.CREATE,
    outcome: 'unknown',
    savedObject: {
      type: 'alert',
      id: ruleId
    }
  }));

  // TODO (http-versioning): Remove casts
  let createdAlert;
  try {
    createdAlert = await (0, _apmUtils.withSpan)({
      name: 'unsecuredSavedObjectsClient.create',
      type: 'rules'
    }, () => (0, _rule.createRuleSo)({
      ruleAttributes: (0, _update_meta.updateMeta)(context, rawRule),
      savedObjectsClient: context.unsecuredSavedObjectsClient,
      savedObjectsCreateOptions: {
        ...options,
        references,
        id: ruleId
      }
    }));
  } catch (e) {
    // Avoid unused API key
    await (0, _bulk_mark_api_keys_for_invalidation.bulkMarkApiKeysForInvalidation)({
      apiKeys: rawRule.apiKey && !rawRule.apiKeyCreatedByUser ? [rawRule.apiKey] : []
    }, context.logger, context.unsecuredSavedObjectsClient);
    throw e;
  }
  if (rawRule.enabled) {
    let scheduledTaskId;
    try {
      const scheduledTask = await (0, _schedule_task.scheduleTask)(context, {
        id: createdAlert.id,
        consumer: rawRule.consumer,
        ruleTypeId: rawRule.alertTypeId,
        schedule: rawRule.schedule,
        throwOnConflict: true
      });
      scheduledTaskId = scheduledTask.id;
    } catch (e) {
      // Cleanup data, something went wrong scheduling the task
      try {
        await (0, _rule.deleteRuleSo)({
          savedObjectsClient: context.unsecuredSavedObjectsClient,
          id: createdAlert.id
        });
      } catch (err) {
        // Skip the cleanup error and throw the task manager error to avoid confusion
        context.logger.error(`Failed to cleanup alert "${createdAlert.id}" after scheduling task failed. Error: ${err.message}`);
      }
      throw e;
    }
    await (0, _apmUtils.withSpan)({
      name: 'unsecuredSavedObjectsClient.update',
      type: 'rules'
    }, () => (0, _rule.updateRuleSo)({
      savedObjectsClient: context.unsecuredSavedObjectsClient,
      id: createdAlert.id,
      updateRuleAttributes: {
        scheduledTaskId
      }
    }));
    createdAlert.attributes.scheduledTaskId = scheduledTaskId;
  }

  // Log warning if schedule interval is less than the minimum but we're not enforcing it
  if (intervalInMs < context.minimumScheduleIntervalInMs && !context.minimumScheduleInterval.enforce) {
    context.logger.warn(`Rule schedule interval (${rawRule.schedule.interval}) for "${createdAlert.attributes.alertTypeId}" rule type with ID "${createdAlert.id}" is less than the minimum value (${context.minimumScheduleInterval.value}). Running rules at this interval may impact alerting performance. Set "xpack.alerting.rules.minimumScheduleInterval.enforce" to true to prevent creation of these rules.`);
  }

  // TODO (http-versioning): Remove casts
  if (returnRuleAttributes) {
    return createdAlert;
  }
  return (0, _get_alert_from_raw.getAlertFromRaw)(context, createdAlert.id, createdAlert.attributes.alertTypeId, createdAlert.attributes, references, false, true);
}