"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.SavedObjectsRepository = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _coreSavedObjectsBaseServerInternal = require("@kbn/core-saved-objects-base-server-internal");
var _point_in_time_finder = require("./point_in_time_finder");
var _repository_es_client = require("./repository_es_client");
var _apis = require("./apis");
var _utils = require("./utils");
/*
 * 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 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */

/**
 * Constructor options for {@link SavedObjectsRepository}
 * @internal
 */

/**
 * Saved Objects Repository - the client entry point for all saved object manipulation.
 *
 * The SOR calls the Elasticsearch client and leverages extension implementations to
 * support spaces, security, and encryption features.
 *
 * @internal
 */
class SavedObjectsRepository {
  /**
   * A factory function for creating SavedObjectRepository instances.
   *
   * @internalRemarks Tests are located in ./repository_create_repository.test.ts
   *
   * @internal
   */
  static createRepository(migrator, typeRegistry, indexName, client, logger, includedHiddenTypes = [], extensions, /** The injectedConstructor is only used for unit testing */
  injectedConstructor = SavedObjectsRepository) {
    const mappings = migrator.getActiveMappings();
    const allTypes = typeRegistry.getAllTypes().map(t => t.name);
    const serializer = new _coreSavedObjectsBaseServerInternal.SavedObjectsSerializer(typeRegistry);
    const visibleTypes = allTypes.filter(type => !typeRegistry.isHidden(type));
    const allowedTypes = [...new Set(visibleTypes.concat(includedHiddenTypes))];
    const missingTypeMappings = includedHiddenTypes.filter(type => !allTypes.includes(type));
    if (missingTypeMappings.length > 0) {
      throw new Error(`Missing mappings for saved objects types: '${missingTypeMappings.join(', ')}'`);
    }
    return new injectedConstructor({
      index: indexName,
      migrator,
      mappings,
      typeRegistry,
      serializer,
      allowedTypes,
      client,
      logger,
      extensions
    });
  }
  constructor(options) {
    (0, _defineProperty2.default)(this, "migrator", void 0);
    (0, _defineProperty2.default)(this, "mappings", void 0);
    (0, _defineProperty2.default)(this, "registry", void 0);
    (0, _defineProperty2.default)(this, "allowedTypes", void 0);
    (0, _defineProperty2.default)(this, "client", void 0);
    (0, _defineProperty2.default)(this, "serializer", void 0);
    (0, _defineProperty2.default)(this, "logger", void 0);
    (0, _defineProperty2.default)(this, "apiExecutionContext", void 0);
    (0, _defineProperty2.default)(this, "extensions", void 0);
    (0, _defineProperty2.default)(this, "helpers", void 0);
    const {
      index,
      mappings,
      client,
      typeRegistry,
      serializer,
      migrator,
      allowedTypes = [],
      logger,
      extensions = {}
    } = options;
    if (allowedTypes.length === 0) {
      throw new Error('Empty or missing types for saved object repository!');
    }
    this.migrator = migrator;
    this.mappings = mappings;
    this.registry = typeRegistry;
    this.client = (0, _repository_es_client.createRepositoryEsClient)(client);
    this.allowedTypes = allowedTypes;
    this.serializer = serializer;
    this.logger = logger;
    this.extensions = extensions;
    this.helpers = (0, _utils.createRepositoryHelpers)({
      logger,
      client: this.client,
      index,
      typeRegistry,
      serializer,
      extensions,
      migrator,
      createPointInTimeFinder: this.createPointInTimeFinder.bind(this)
    });
    this.apiExecutionContext = {
      client: this.client,
      extensions: this.extensions,
      helpers: this.helpers,
      allowedTypes: this.allowedTypes,
      registry: this.registry,
      serializer: this.serializer,
      migrator: this.migrator,
      mappings: this.mappings,
      logger: this.logger
    };
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.create}
   */
  async create(type, attributes, options = {}) {
    return await (0, _apis.performCreate)({
      type,
      attributes,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.bulkCreate}
   */
  async bulkCreate(objects, options = {}) {
    return await (0, _apis.performBulkCreate)({
      objects,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.checkConflicts}
   */
  async checkConflicts(objects = [], options = {}) {
    return await (0, _apis.performCheckConflicts)({
      objects,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.delete}
   */
  async delete(type, id, options = {}) {
    return await (0, _apis.performDelete)({
      type,
      id,
      options
    }, this.apiExecutionContext);
  }

  /**
   *  {@inheritDoc ISavedObjectsRepository.bulkDelete}
   */
  async bulkDelete(objects, options = {}) {
    return await (0, _apis.performBulkDelete)({
      objects,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.deleteByNamespace}
   */
  async deleteByNamespace(namespace, options = {}) {
    return await (0, _apis.performDeleteByNamespace)({
      namespace,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.find}
   */
  async find(options, internalOptions = {}) {
    return await (0, _apis.performFind)({
      options,
      internalOptions
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.bulkGet}
   */
  async bulkGet(objects = [], options = {}) {
    return await (0, _apis.performBulkGet)({
      objects,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.bulkResolve}
   */
  async bulkResolve(objects, options = {}) {
    return await (0, _apis.performBulkResolve)({
      objects,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.get}
   */
  async get(type, id, options = {}) {
    return await (0, _apis.performGet)({
      type,
      id,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.resolve}
   */
  async resolve(type, id, options = {}) {
    return await (0, _apis.performResolve)({
      type,
      id,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.update}
   */
  async update(type, id, attributes, options = {}) {
    return await (0, _apis.performUpdate)({
      type,
      id,
      attributes,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.collectMultiNamespaceReferences}
   */
  async collectMultiNamespaceReferences(objects, options = {}) {
    return await (0, _apis.performCollectMultiNamespaceReferences)({
      objects,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.updateObjectsSpaces}
   */
  async updateObjectsSpaces(objects, spacesToAdd, spacesToRemove, options = {}) {
    return await (0, _apis.performUpdateObjectsSpaces)({
      objects,
      spacesToAdd,
      spacesToRemove,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.bulkUpdate}
   */
  async bulkUpdate(objects, options = {}) {
    return await (0, _apis.performBulkUpdate)({
      objects,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.removeReferencesTo}
   */
  async removeReferencesTo(type, id, options = {}) {
    return await (0, _apis.performRemoveReferencesTo)({
      type,
      id,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.incrementCounter}
   */
  async incrementCounter(type, id, counterFields, options = {}) {
    return await (0, _apis.performIncrementCounter)({
      type,
      id,
      counterFields,
      options
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.openPointInTimeForType}
   */
  async openPointInTimeForType(type, options = {}, internalOptions = {}) {
    return await (0, _apis.performOpenPointInTime)({
      type,
      options,
      internalOptions
    }, this.apiExecutionContext);
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.closePointInTime}
   */
  async closePointInTime(id, options, internalOptions = {}) {
    const {
      disableExtensions
    } = internalOptions;
    if (!disableExtensions && this.extensions.securityExtension) {
      this.extensions.securityExtension.auditClosePointInTime();
    }
    return await this.client.closePointInTime({
      body: {
        id
      }
    });
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.createPointInTimeFinder}
   */
  createPointInTimeFinder(findOptions, dependencies, internalOptions) {
    return new _point_in_time_finder.PointInTimeFinder(findOptions, {
      logger: this.logger,
      client: this,
      ...dependencies,
      internalOptions
    });
  }

  /**
   * {@inheritDoc ISavedObjectsRepository.getCurrentNamespace}
   */
  getCurrentNamespace(namespace) {
    return this.helpers.common.getCurrentNamespace(namespace);
  }
}
exports.SavedObjectsRepository = SavedObjectsRepository;