text: /* eslint-disable prefer-template */
  /*!
   * Copyright (c) 2015-2017 Cisco Systems, Inc. See LICENSE file.
   */
  
  import {waitForValue, SparkPlugin} from '@ciscospark/spark-core';
  
  import ReportGenerator from './report-generator';
  
  /**
   * @class EDiscovery is used by compliance officers to run compliance reports
   *
   */
  const EDiscovery = SparkPlugin.extend({
    namespace: 'EDiscovery',
  
    @waitForValue('@')
    /**
     * Creates a compliance report with a specific set of search parameters
     * @param {Object} reportRequest - A set of criteria for determining the focus of the search
     * @returns {Promise<ResponseEntity>} Http response containing the new report record
     */
    createReport(reportRequest) {
      if (!reportRequest || !reportRequest.emails || !reportRequest.range) {
        throw Error('Invalid parameter(s)');
      }
  
      const body = reportRequest;
      return this.request({
        method: 'POST',
        service: 'ediscovery',
        resource: 'reports',
        body
      })
        .catch((reason) => {
          throw Error(reason);
        });
    },
  
    @waitForValue('@')
    /**
     * Retrieves information relating to a specified report
     * @param {UUID} reportId - Id of the report being requested
     * @returns {Promise<ResponseEntity<ReportRecord>>} Http response containing the specified report record
     */
    getReport(reportId) {
      if (!reportId) {
        throw Error('Invalid parameter(s)');
      }
  
      return this.request({
        method: 'GET',
        service: 'ediscovery',
        resource: `reports/${reportId}`
      })
        .catch((reason) => {
          throw Error(reason);
        });
    },
  
    @waitForValue('@')
    /**
     * Retrieves all the compliance officers reports
     * @returns {Promise<ResponseEntity<Array<ReportRecord>>>} Http Response containing a list of report records
     */
    getReports() {
      return this.request({
        method: 'GET',
        service: 'ediscovery',
        resource: 'reports'
      })
        .catch((reason) => {
          throw Error(reason);
        });
    },
  
    @waitForValue('@')
    /**
     * Deletes a specified report
     * @param {UUID} reportId - Id of the report being requested for deletion
     * @returns {Promise<ResponseEntity>} HttpResponse indicating if delete was successful
     */
    deleteReport(reportId) {
      if (!reportId) {
        throw Error('Invalid parameter(s)');
      }
  
      return this.request({
        method: 'DELETE',
        service: 'ediscovery',
        resource: `reports/${reportId}`
      })
        .catch((reason) => {
          throw Error(reason);
        });
    },
  
    @waitForValue('@')
    /**
     * Restarts a completed or cancelled report so that it begins again from scratch
     * @param {UUID} reportId - Id of the report being requested
     * @returns {Promise<ResponseEntity<ReportRecord>>} Http response containing the report record
     */
    restartReport(reportId) {
      if (!reportId) {
        throw Error('Invalid parameter(s)');
      }
  
      return this.request({
        method: 'PUT',
        service: 'ediscovery',
        resource: `reports/${reportId}`
      })
        .catch((reason) => {
          throw Error(reason);
        });
    },
  
    @waitForValue('@')
    /**
     * Retrieves a list of the conversations relevant to a specified report
     * @param {UUID} reportId - Id of the report being requested
     * @returns {Promise<ResponseEntity<ContentSummary>>} Http response containing the content summary
     */
    getContentSummary(reportId) {
      if (!reportId) {
        throw Error('Invalid parameter(s)');
      }
  
      let offset = 0;
      const size = 100;
      let contentSummary = [];
  
      function getNextContentSummaryPage(plugin) {
        return plugin.request({
          method: 'GET',
          service: 'ediscovery',
          resource: `reports/${reportId}/contents/summary`,
          qs: {offset, size}
        })
          .then((res) => {
            contentSummary = contentSummary.concat(res.body);
            if (res.body.length < size) {
              return contentSummary;
            }
            offset += size;
            return getNextContentSummaryPage(plugin);
          })
          .catch((reason) => {
            throw Error(reason);
          });
      }
  
      return getNextContentSummaryPage(this);
    },
  
    @waitForValue('@')
    /**
     * Retrieves a list of the conversations relevant to a specified report, paged with a specified offset and size
     * @param {UUID} reportId - Id of the report being requested
     * @param {long} offset - the starting index of the results the caller wants
     * @param {long} size - the number of conversations the caller wants
     * @returns {Promise<ResponseEntity<ContentSummary>>} Http response containing the specified content summary
     */
    getPagedContentSummary(reportId, offset, size) {
      if (!reportId) {
        throw Error('Invalid parameter(s)');
      }
  
      return this.request({
        method: 'GET',
        service: 'ediscovery',
        resource: `reports/${reportId}/contents/summary`,
        qs: {offset, size}
      })
        .catch((reason) => {
          throw Error(reason);
        });
    },
  
    @waitForValue('@')
    /**
     * Generates the report content and triggers the download of the content
     * @param {UUID} reportId - Id of the report being requested
     * @returns {List<Activities>} HttpResponse
     */
    generateReport(reportId) {
      if (!reportId) {
        throw Error('Invalid parameter(s)');
      }
  
      let offset = 0;
      const size = 100;
      const reportGenerator = new ReportGenerator({reportId});
  
      function processNextActivities(plugin) {
        return plugin.request({
          method: 'GET',
          service: 'ediscovery',
          resource: `reports/${reportId}/contents`,
          qs: {offset, size}
        })
          .then((res) => {
            const contents = res.body;
            return plugin._downloadFileContent(contents);
          })
          .then((activities) => {
            if (activities && Array.isArray(activities) && activities.length > 0) {
              reportGenerator.add(activities);
              if (activities.length < size) {
                // No more activities to decrypt
              }
              else {
                // Add activities to the report, increment and decrypt next activities
                offset += size;
                return processNextActivities(plugin);
              }
            }
            return Promise.resolve();
          })
          .catch((reason) => {
            throw Error(reason);
          });
      }
  
      return processNextActivities(this).then(() => reportGenerator.saveAs());
    },
  
    /**
     * Decrypt the activities found in the report content
     * @param {Object[]} activities An array of activities with encrypted messages
     * @returns {Promise<[any]>} The activities with their messages decrypted
     */
    _downloadFileContent(activities) {
      const promises = [];
      for (let i = 0; i < activities.length; i += 1) {
        const activity = activities[i];
        if (activity.verb === 'share' && activity.files && activity.files.length) {
          for (let i = 0; i < activity.files.length; i += 1) {
            const file = activity.files[i];
            if (file && file.scr && file.scr.loc) {
              promises.push(this.spark.internal.encryption.download(file.scr)
                .then((content) => {
                  file.content = content;
                })
                .catch((reason) => {
                  this.logger.error(`Unable to download file content for activity ${activity.activityId} due to error: ${reason}`);
                }));
            }
          }
        }
      }
      return Promise.all(promises)
        .then(() => activities);
    }
  
  });
  
  export default EDiscovery;
  