"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.deleteAll = deleteAll;
exports.deleteComment = deleteComment;
var _boom = _interopRequireDefault(require("@hapi/boom"));
var _domain = require("../../../common/types/domain");
var _api = require("../../../common/api");
var _constants = require("../../../common/constants");
var _utils = require("../../common/utils");
var _error = require("../../common/error");
var _authorization = require("../../authorization");
var _api2 = require("../../../common/types/api");
/*
 * 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.
 */

/**
 * Delete all comments for a case.
 */
async function deleteAll({
  caseID
}, clientArgs) {
  const {
    user,
    services: {
      caseService,
      attachmentService,
      userActionService,
      alertsService
    },
    logger,
    authorization
  } = clientArgs;
  try {
    const comments = await caseService.getAllCaseComments({
      id: caseID
    });
    if (comments.total <= 0) {
      throw _boom.default.notFound(`No comments found for ${caseID}.`);
    }
    await authorization.ensureAuthorized({
      operation: _authorization.Operations.deleteAllComments,
      entities: comments.saved_objects.map(comment => ({
        owner: comment.attributes.owner,
        id: comment.id
      }))
    });
    await attachmentService.bulkDelete({
      attachmentIds: comments.saved_objects.map(so => so.id),
      refresh: false
    });
    await userActionService.creator.bulkCreateAttachmentDeletion({
      caseId: caseID,
      attachments: comments.saved_objects.map(comment => ({
        id: comment.id,
        owner: comment.attributes.owner,
        attachment: comment.attributes
      })),
      user
    });
    const attachments = comments.saved_objects.map(comment => comment.attributes);
    await handleAlerts({
      alertsService,
      attachments,
      caseId: caseID
    });
  } catch (error) {
    throw (0, _error.createCaseError)({
      message: `Failed to delete all comments case id: ${caseID}: ${error}`,
      error,
      logger
    });
  }
}

/**
 * Deletes an attachment
 */
async function deleteComment({
  caseID,
  attachmentID
}, clientArgs) {
  const {
    user,
    services: {
      attachmentService,
      userActionService,
      alertsService
    },
    logger,
    authorization
  } = clientArgs;
  try {
    const attachment = await attachmentService.getter.get({
      attachmentId: attachmentID
    });
    if (attachment == null) {
      throw _boom.default.notFound(`This comment ${attachmentID} does not exist anymore.`);
    }
    await authorization.ensureAuthorized({
      entities: [{
        owner: attachment.attributes.owner,
        id: attachment.id
      }],
      operation: _authorization.Operations.deleteComment
    });
    const type = _constants.CASE_SAVED_OBJECT;
    const id = caseID;
    const caseRef = attachment.references.find(c => c.type === type);
    if (caseRef == null || caseRef != null && caseRef.id !== id) {
      throw _boom.default.notFound(`This comment ${attachmentID} does not exist in ${id}.`);
    }
    await attachmentService.bulkDelete({
      attachmentIds: [attachmentID],
      refresh: false
    });

    // we only want to store the fields related to the original request of the attachment, not fields like
    // created_at etc. So we'll use the decode to strip off the other fields. This is necessary because we don't know
    // what type of attachment this is. Depending on the type it could have various fields.
    const attachmentRequestAttributes = (0, _api.decodeOrThrow)(_api2.AttachmentRequestRt)(attachment.attributes);
    await userActionService.creator.createUserAction({
      type: _domain.UserActionTypes.comment,
      action: _domain.UserActionActions.delete,
      caseId: id,
      attachmentId: attachmentID,
      payload: {
        attachment: attachmentRequestAttributes
      },
      user,
      owner: attachment.attributes.owner
    });
    await handleAlerts({
      alertsService,
      attachments: [attachment.attributes],
      caseId: id
    });
  } catch (error) {
    throw (0, _error.createCaseError)({
      message: `Failed to delete comment: ${caseID} comment id: ${attachmentID}: ${error}`,
      error,
      logger
    });
  }
}
const handleAlerts = async ({
  alertsService,
  attachments,
  caseId
}) => {
  const alertAttachments = attachments.filter(attachment => (0, _utils.isCommentRequestTypeAlert)(attachment));
  if (alertAttachments.length === 0) {
    return;
  }
  const alerts = (0, _utils.getAlertInfoFromComments)(alertAttachments);
  await alertsService.removeCaseIdFromAlerts({
    alerts,
    caseId
  });
};