"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.find = find;
exports.get = get;
exports.getAll = getAll;
exports.getAllAlertsAttachToCase = void 0;
var _common = require("../../../common");
var _api = require("../../../common/types/api");
var _constants = require("../../../common/constants");
var _api2 = require("../../../common/api");
var _utils = require("../../common/utils");
var _error = require("../../common/error");
var _api3 = require("../../routes/api");
var _utils2 = require("../utils");
var _authorization = require("../../authorization");
var _runtime_types = require("../../../common/api/runtime_types");
var _domain = require("../../../common/types/domain");
/*
 * 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.
 */

const normalizeAlertResponse = alerts => alerts.reduce((acc, alert) => {
  const {
    ids,
    indices
  } = (0, _utils.getIDsAndIndicesAsArrays)(alert.attributes);
  if (ids.length !== indices.length) {
    return acc;
  }
  acc.push(...ids.map((id, index) => ({
    id,
    index: indices[index],
    attached_at: alert.attributes.created_at
  })));
  return acc;
}, []);

/**
 * Retrieves all alerts attached to a specific case.
 */
const getAllAlertsAttachToCase = async ({
  caseId
}, clientArgs, casesClient) => {
  const {
    authorization,
    services: {
      attachmentService
    },
    logger
  } = clientArgs;
  try {
    // This will perform an authorization check to ensure the user has access to the parent case
    const theCase = await casesClient.cases.get({
      id: caseId,
      includeComments: false
    });
    const {
      filter: authorizationFilter,
      ensureSavedObjectsAreAuthorized
    } = await authorization.getAuthorizationFilter(_authorization.Operations.getAlertsAttachedToCase);
    const alerts = await attachmentService.getter.getAllAlertsAttachToCase({
      caseId: theCase.id,
      filter: authorizationFilter
    });
    ensureSavedObjectsAreAuthorized(alerts.map(alert => ({
      owner: alert.attributes.owner,
      id: alert.id
    })));
    const res = normalizeAlertResponse(alerts);
    return (0, _runtime_types.decodeOrThrow)(_api.AlertResponseRt)(res);
  } catch (error) {
    throw (0, _error.createCaseError)({
      message: `Failed to get alerts attached to case id: ${caseId}: ${error}`,
      error,
      logger
    });
  }
};

/**
 * Retrieves the attachments for a case entity. This support pagination.
 */
exports.getAllAlertsAttachToCase = getAllAlertsAttachToCase;
async function find({
  caseID,
  findQueryParams
}, clientArgs) {
  const {
    services: {
      attachmentService
    },
    logger,
    authorization
  } = clientArgs;
  try {
    var _queryParams$page, _queryParams$perPage;
    const queryParams = (0, _api2.decodeWithExcessOrThrow)(_api.FindAttachmentsQueryParamsRt)(findQueryParams);
    const {
      filter: authorizationFilter,
      ensureSavedObjectsAreAuthorized
    } = await authorization.getAuthorizationFilter(_authorization.Operations.findComments);
    const filter = (0, _utils2.combineFilters)([(0, _utils2.buildFilter)({
      filters: [_common.AttachmentType.user],
      field: 'type',
      operator: 'or',
      type: _constants.CASE_COMMENT_SAVED_OBJECT
    }), authorizationFilter]);
    const theComments = await attachmentService.find({
      options: {
        page: (_queryParams$page = queryParams === null || queryParams === void 0 ? void 0 : queryParams.page) !== null && _queryParams$page !== void 0 ? _queryParams$page : _api3.DEFAULT_PAGE,
        perPage: (_queryParams$perPage = queryParams === null || queryParams === void 0 ? void 0 : queryParams.perPage) !== null && _queryParams$perPage !== void 0 ? _queryParams$perPage : _api3.DEFAULT_PER_PAGE,
        ...((queryParams === null || queryParams === void 0 ? void 0 : queryParams.sortOrder) && {
          sortOrder: queryParams === null || queryParams === void 0 ? void 0 : queryParams.sortOrder
        }),
        sortField: 'created_at',
        hasReference: {
          type: _constants.CASE_SAVED_OBJECT,
          id: caseID
        },
        filter
      }
    });
    ensureSavedObjectsAreAuthorized(theComments.saved_objects.map(comment => ({
      owner: comment.attributes.owner,
      id: comment.id
    })));
    const res = (0, _utils.transformComments)(theComments);
    return (0, _runtime_types.decodeOrThrow)(_api.AttachmentsFindResponseRt)(res);
  } catch (error) {
    throw (0, _error.createCaseError)({
      message: `Failed to find comments case id: ${caseID}: ${error}`,
      error,
      logger
    });
  }
}

/**
 * Retrieves a single attachment by its ID.
 */
async function get({
  attachmentID,
  caseID
}, clientArgs) {
  const {
    services: {
      attachmentService
    },
    logger,
    authorization
  } = clientArgs;
  try {
    const comment = await attachmentService.getter.get({
      attachmentId: attachmentID
    });
    await authorization.ensureAuthorized({
      entities: [{
        owner: comment.attributes.owner,
        id: comment.id
      }],
      operation: _authorization.Operations.getComment
    });
    const res = (0, _utils.flattenCommentSavedObject)(comment);
    return (0, _runtime_types.decodeOrThrow)(_domain.AttachmentRt)(res);
  } catch (error) {
    throw (0, _error.createCaseError)({
      message: `Failed to get comment case id: ${caseID} attachment id: ${attachmentID}: ${error}`,
      error,
      logger
    });
  }
}

/**
 * Retrieves all the attachments for a case.
 */
async function getAll({
  caseID
}, clientArgs) {
  const {
    services: {
      caseService
    },
    logger,
    authorization
  } = clientArgs;
  try {
    const {
      filter,
      ensureSavedObjectsAreAuthorized
    } = await authorization.getAuthorizationFilter(_authorization.Operations.getAllComments);
    const comments = await caseService.getAllCaseComments({
      id: caseID,
      options: {
        filter,
        sortField: _utils.defaultSortField
      }
    });
    ensureSavedObjectsAreAuthorized(comments.saved_objects.map(comment => ({
      id: comment.id,
      owner: comment.attributes.owner
    })));
    const res = (0, _utils.flattenCommentSavedObjects)(comments.saved_objects);
    return (0, _runtime_types.decodeOrThrow)(_domain.AttachmentsRt)(res);
  } catch (error) {
    throw (0, _error.createCaseError)({
      message: `Failed to get all comments case id: ${caseID}: ${error}`,
      error,
      logger
    });
  }
}