"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.SavedObjectTypeRegistry = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _std = require("@kbn/std");
/*
 * 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.
 */

/**
 * Core internal implementation of {@link ISavedObjectTypeRegistry}.
 *
 * @internal should only be used outside of Core for testing purposes.
 */
class SavedObjectTypeRegistry {
  constructor() {
    (0, _defineProperty2.default)(this, "types", new Map());
  }
  /**
   * Register a {@link SavedObjectsType | type} inside the registry.
   * A type can only be registered once. subsequent calls with the same type name will throw an error.
   *
   * @internal
   */
  registerType(type) {
    if (this.types.has(type.name)) {
      throw new Error(`Type '${type.name}' is already registered`);
    }
    validateType(type);
    this.types.set(type.name, (0, _std.deepFreeze)(type));
  }

  /** {@inheritDoc ISavedObjectTypeRegistry.getType} */
  getType(type) {
    return this.types.get(type);
  }

  /** {@inheritDoc ISavedObjectTypeRegistry.getVisibleTypes} */
  getVisibleTypes() {
    return [...this.types.values()].filter(type => !this.isHidden(type.name));
  }

  /** {@inheritDoc ISavedObjectTypeRegistry.getVisibleToHttpApisTypes}  */
  getVisibleToHttpApisTypes() {
    return [...this.types.values()].filter(type => !this.isHiddenFromHttpApis(type.name));
  }

  /** {@inheritDoc ISavedObjectTypeRegistry.getAllTypes} */
  getAllTypes() {
    return [...this.types.values()];
  }

  /** {@inheritDoc ISavedObjectTypeRegistry.getImportableAndExportableTypes} */
  getImportableAndExportableTypes() {
    return this.getAllTypes().filter(type => this.isImportableAndExportable(type.name));
  }

  /** {@inheritDoc ISavedObjectTypeRegistry.isNamespaceAgnostic} */
  isNamespaceAgnostic(type) {
    var _this$types$get;
    return ((_this$types$get = this.types.get(type)) === null || _this$types$get === void 0 ? void 0 : _this$types$get.namespaceType) === 'agnostic';
  }

  /** {@inheritDoc ISavedObjectTypeRegistry.isSingleNamespace} */
  isSingleNamespace(type) {
    // in the case we somehow registered a type with an invalid `namespaceType`, treat it as single-namespace
    return !this.isNamespaceAgnostic(type) && !this.isMultiNamespace(type);
  }

  /** {@inheritDoc ISavedObjectTypeRegistry.isMultiNamespace} */
  isMultiNamespace(type) {
    var _this$types$get2;
    const namespaceType = (_this$types$get2 = this.types.get(type)) === null || _this$types$get2 === void 0 ? void 0 : _this$types$get2.namespaceType;
    return namespaceType === 'multiple' || namespaceType === 'multiple-isolated';
  }

  /** {@inheritDoc ISavedObjectTypeRegistry.isShareable} */
  isShareable(type) {
    var _this$types$get3;
    return ((_this$types$get3 = this.types.get(type)) === null || _this$types$get3 === void 0 ? void 0 : _this$types$get3.namespaceType) === 'multiple';
  }

  /** {@inheritDoc ISavedObjectTypeRegistry.isHidden} */
  isHidden(type) {
    var _this$types$get$hidde, _this$types$get4;
    return (_this$types$get$hidde = (_this$types$get4 = this.types.get(type)) === null || _this$types$get4 === void 0 ? void 0 : _this$types$get4.hidden) !== null && _this$types$get$hidde !== void 0 ? _this$types$get$hidde : false;
  }

  /** {@inheritDoc ISavedObjectTypeRegistry.isHiddenFromHttpApi} */
  isHiddenFromHttpApis(type) {
    var _this$types$get5;
    return !!((_this$types$get5 = this.types.get(type)) !== null && _this$types$get5 !== void 0 && _this$types$get5.hiddenFromHttpApis);
  }

  /** {@inheritDoc ISavedObjectTypeRegistry.getType} */
  getIndex(type) {
    var _this$types$get6;
    return (_this$types$get6 = this.types.get(type)) === null || _this$types$get6 === void 0 ? void 0 : _this$types$get6.indexPattern;
  }

  /** {@inheritDoc ISavedObjectTypeRegistry.isImportableAndExportable} */
  isImportableAndExportable(type) {
    var _this$types$get$manag, _this$types$get7, _this$types$get7$mana;
    return (_this$types$get$manag = (_this$types$get7 = this.types.get(type)) === null || _this$types$get7 === void 0 ? void 0 : (_this$types$get7$mana = _this$types$get7.management) === null || _this$types$get7$mana === void 0 ? void 0 : _this$types$get7$mana.importableAndExportable) !== null && _this$types$get$manag !== void 0 ? _this$types$get$manag : false;
  }
}
exports.SavedObjectTypeRegistry = SavedObjectTypeRegistry;
const validateType = ({
  name,
  management,
  hidden,
  hiddenFromHttpApis
}) => {
  if (management) {
    if (management.onExport && !management.importableAndExportable) {
      throw new Error(`Type ${name}: 'management.importableAndExportable' must be 'true' when specifying 'management.onExport'`);
    }
    if (management.visibleInManagement !== undefined && !management.importableAndExportable) {
      throw new Error(`Type ${name}: 'management.importableAndExportable' must be 'true' when specifying 'management.visibleInManagement'`);
    }
  }
  // throw error if a type is registered as `hidden:true` and `hiddenFromHttpApis:false` explicitly
  if (hidden === true && hiddenFromHttpApis === false) {
    throw new Error(`Type ${name}: 'hiddenFromHttpApis' cannot be 'false' when specifying 'hidden' as 'true'`);
  }
};