"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.importSavedObjectsFromStream = importSavedObjectsFromStream;
var _lib = require("./lib");
/*
 * 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.
 */

/**
 * Options to control the import operation.
 */

/**
 * Import saved objects from given stream. See the {@link SavedObjectsImportOptions | options} for more
 * detailed information.
 *
 * @public
 */
async function importSavedObjectsFromStream({
  readStream,
  objectLimit,
  overwrite,
  createNewCopies,
  savedObjectsClient,
  typeRegistry,
  importHooks,
  namespace,
  refresh,
  compatibilityMode,
  managed
}) {
  let errorAccumulator = [];
  const supportedTypes = typeRegistry.getImportableAndExportableTypes().map(type => type.name);

  // Get the objects to import
  const collectSavedObjectsResult = await (0, _lib.collectSavedObjects)({
    readStream,
    objectLimit,
    supportedTypes,
    managed
  });
  errorAccumulator = [...errorAccumulator, ...collectSavedObjectsResult.errors];
  // Map of all IDs for objects that we are attempting to import, and any references that are not included in the read stream;
  // each value is empty by default
  let importStateMap = collectSavedObjectsResult.importStateMap;
  let pendingOverwrites = new Set();

  // Check any references that aren't included in the import file and retries, to see if they have a match with a different origin
  const checkReferenceOriginsResult = await (0, _lib.checkReferenceOrigins)({
    savedObjectsClient,
    typeRegistry,
    namespace,
    importStateMap
  });
  importStateMap = new Map([...importStateMap, ...checkReferenceOriginsResult.importStateMap]);

  // Validate references
  const validateReferencesResult = await (0, _lib.validateReferences)({
    objects: collectSavedObjectsResult.collectedObjects,
    savedObjectsClient,
    namespace,
    importStateMap
  });
  errorAccumulator = [...errorAccumulator, ...validateReferencesResult];
  if (createNewCopies) {
    importStateMap = new Map([...importStateMap,
    // preserve any entries for references that aren't included in collectedObjects
    ...(0, _lib.regenerateIds)(collectSavedObjectsResult.collectedObjects)]);
  } else {
    // Check single-namespace objects for conflicts in this namespace, and check multi-namespace objects for conflicts across all namespaces
    const checkConflictsParams = {
      objects: collectSavedObjectsResult.collectedObjects,
      savedObjectsClient,
      namespace,
      ignoreRegularConflicts: overwrite
    };
    const checkConflictsResult = await (0, _lib.checkConflicts)(checkConflictsParams);
    errorAccumulator = [...errorAccumulator, ...checkConflictsResult.errors];
    importStateMap = new Map([...importStateMap, ...checkConflictsResult.importStateMap]);
    pendingOverwrites = checkConflictsResult.pendingOverwrites;

    // Check multi-namespace object types for origin conflicts in this namespace
    const checkOriginConflictsParams = {
      objects: checkConflictsResult.filteredObjects,
      savedObjectsClient,
      typeRegistry,
      namespace,
      ignoreRegularConflicts: overwrite,
      importStateMap,
      pendingOverwrites
    };
    const checkOriginConflictsResult = await (0, _lib.checkOriginConflicts)(checkOriginConflictsParams);
    errorAccumulator = [...errorAccumulator, ...checkOriginConflictsResult.errors];
    importStateMap = new Map([...importStateMap, ...checkOriginConflictsResult.importStateMap]);
    pendingOverwrites = new Set([...pendingOverwrites, ...checkOriginConflictsResult.pendingOverwrites]);
  }

  // Create objects in bulk
  const createSavedObjectsParams = {
    objects: collectSavedObjectsResult.collectedObjects,
    accumulatedErrors: errorAccumulator,
    savedObjectsClient,
    importStateMap,
    overwrite,
    namespace,
    refresh,
    compatibilityMode,
    managed
  };
  const createSavedObjectsResult = await (0, _lib.createSavedObjects)(createSavedObjectsParams);
  errorAccumulator = [...errorAccumulator, ...createSavedObjectsResult.errors];
  const successResults = createSavedObjectsResult.createdObjects.map(createdObject => {
    var _typeRegistry$getType, _typeRegistry$getType2, _typeRegistry$getType3, _typeRegistry$getType4;
    const {
      type,
      id,
      destinationId,
      originId,
      managed: createdObjectManaged
    } = createdObject;
    const getTitle = (_typeRegistry$getType = typeRegistry.getType(type)) === null || _typeRegistry$getType === void 0 ? void 0 : (_typeRegistry$getType2 = _typeRegistry$getType.management) === null || _typeRegistry$getType2 === void 0 ? void 0 : _typeRegistry$getType2.getTitle;
    const meta = {
      title: getTitle ? getTitle(createdObject) : createdObject.attributes.title,
      icon: (_typeRegistry$getType3 = typeRegistry.getType(type)) === null || _typeRegistry$getType3 === void 0 ? void 0 : (_typeRegistry$getType4 = _typeRegistry$getType3.management) === null || _typeRegistry$getType4 === void 0 ? void 0 : _typeRegistry$getType4.icon
    };
    const attemptedOverwrite = pendingOverwrites.has(`${type}:${id}`);
    return {
      type,
      id,
      meta,
      managed: createdObjectManaged !== null && createdObjectManaged !== void 0 ? createdObjectManaged : managed,
      ...(attemptedOverwrite && {
        overwrite: true
      }),
      ...(destinationId && {
        destinationId
      }),
      ...(destinationId && !originId && !createNewCopies && {
        createNewCopy: true
      })
    };
  });
  const errorResults = errorAccumulator.map(error => {
    var _typeRegistry$getType5, _typeRegistry$getType6;
    const icon = (_typeRegistry$getType5 = typeRegistry.getType(error.type)) === null || _typeRegistry$getType5 === void 0 ? void 0 : (_typeRegistry$getType6 = _typeRegistry$getType5.management) === null || _typeRegistry$getType6 === void 0 ? void 0 : _typeRegistry$getType6.icon;
    const attemptedOverwrite = pendingOverwrites.has(`${error.type}:${error.id}`);
    return {
      ...error,
      meta: {
        ...error.meta,
        icon
      },
      ...(attemptedOverwrite && {
        overwrite: true
      })
    };
  });
  const warnings = await (0, _lib.executeImportHooks)({
    objects: createSavedObjectsResult.createdObjects,
    importHooks
  });
  return {
    successCount: createSavedObjectsResult.createdObjects.length,
    success: errorAccumulator.length === 0,
    warnings,
    ...(successResults.length && {
      successResults
    }),
    ...(errorResults.length && {
      errors: errorResults
    })
  };
}