"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.bulkGet = bulkGet;
var _lodash = require("lodash");
var _api = require("../../../common/types/api");
var _api2 = require("../../../common/api");
var _utils = require("../../common/utils");
var _error = require("../../common/error");
var _authorization = require("../../authorization");
var _partitioning = require("../../common/partitioning");
var _runtime_types = require("../../../common/api/runtime_types");
/*
 * 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.
 */

/**
 * Retrieves multiple attachments by id.
 */
async function bulkGet({
  attachmentIDs,
  caseID
}, clientArgs, casesClient) {
  const {
    services: {
      attachmentService
    },
    logger,
    authorization
  } = clientArgs;
  try {
    const request = (0, _api2.decodeWithExcessOrThrow)(_api.BulkGetAttachmentsRequestRt)({
      ids: attachmentIDs
    });

    // perform an authorization check for the case
    await casesClient.cases.resolve({
      id: caseID
    });
    const attachments = await attachmentService.getter.bulkGet(request.ids);
    const {
      validAttachments,
      attachmentsWithErrors,
      invalidAssociationAttachments
    } = partitionAttachments(caseID, attachments);
    const {
      authorized: authorizedAttachments,
      unauthorized: unauthorizedAttachments
    } = await authorization.getAndEnsureAuthorizedEntities({
      savedObjects: validAttachments,
      operation: _authorization.Operations.bulkGetAttachments
    });
    const errors = constructErrors({
      associationErrors: invalidAssociationAttachments,
      unauthorizedAttachments,
      soBulkGetErrors: attachmentsWithErrors,
      caseId: caseID
    });
    const res = {
      attachments: (0, _utils.flattenCommentSavedObjects)(authorizedAttachments),
      errors
    };
    return (0, _runtime_types.decodeOrThrow)(_api.BulkGetAttachmentsResponseRt)(res);
  } catch (error) {
    throw (0, _error.createCaseError)({
      message: `Failed to bulk get attachments for case id: ${caseID}: ${error}`,
      error,
      logger
    });
  }
}
const partitionAttachments = (caseId, attachments) => {
  const [attachmentsWithoutErrors, errors] = partitionBySOError(attachments.saved_objects);
  const [caseAttachments, invalidAssociationAttachments] = (0, _partitioning.partitionByCaseAssociation)(caseId, attachmentsWithoutErrors);
  return {
    validAttachments: caseAttachments,
    attachmentsWithErrors: errors,
    invalidAssociationAttachments
  };
};
const partitionBySOError = attachments => (0, _lodash.partition)(attachments, attachment => attachment.error == null && attachment.attributes != null);
const constructErrors = ({
  caseId,
  soBulkGetErrors,
  associationErrors,
  unauthorizedAttachments
}) => {
  const errors = [];
  for (const soError of soBulkGetErrors) {
    errors.push({
      error: soError.error.error,
      message: soError.error.message,
      status: soError.error.statusCode,
      attachmentId: soError.id
    });
  }
  for (const attachment of associationErrors) {
    errors.push({
      error: 'Bad Request',
      message: `Attachment is not attached to case id=${caseId}`,
      status: 400,
      attachmentId: attachment.id
    });
  }
  for (const unauthorizedAttachment of unauthorizedAttachments) {
    errors.push({
      error: 'Forbidden',
      message: `Unauthorized to access attachment with owner: "${unauthorizedAttachment.attributes.owner}"`,
      status: 403,
      attachmentId: unauthorizedAttachment.id
    });
  }
  return errors;
};