<commit_before>const when = require('when');
const validator = require('../validator');

/**
 * @description Message Object
 *
 * @namespace Message
 * @property {String} id - Message ID
 * @property {String} roomId - Room ID
 * @property {String} roomType - Room Type
 * @property {String} toPersonId - Person ID
 * @property {String} toPersonEmail - Person Email
 * @property {String} text - Message text
 * @property {String} markdown - Message markdown
 * @property {Array.<String>} files - Array of File URLs
 * @property {String} personId - Person ID
 * @property {String} personEmail - Person Email
 * @property {String} created - Date Message created (ISO 8601)
 * @property {Array.String} mentionedPeople - Person IDs of those mentioned in Message
 */

const Messages = (Spark) => {
  const messages = {
    /**
     * @description Returns Spark Message Objects. If 'max' is not specifed, returns all.
     *
     * @memberof Spark
     * @function
     * @param {Object} messageSearch Spark Message Search Object
     * @param {Integer} [max] Number of records to return (optional)
     * @returns {Promise.Array.<Message>} Array of Spark Message objects
     *
     * @example
     * spark.messagesGet({roomId: 'Tm90aGluZyB0byBzZWUgaGVy'}, 100)
     *   .then(messages => messages.forEach(message => console.log(message.text)))
     *   .catch(err => console.error(err));
     */
    messagesGet: (...args) => {
      const messageSearch = args.length > 0 && typeof args[0] === 'object' ? args.shift() : {};
      const maxResults = args.length > 0 && typeof args[0] === 'number' ? args.shift() : 0;

      if (!validator.isMessageSearch(messageSearch)) {
        return when.reject(new Error('invalid search'));
      }
      messageSearch.max = Spark.maxPageItems;
      return Spark.request('get', 'messages', messageSearch, maxResults);
    },

    /**
     * @description Return details of Spark Message by ID.
     *
     * @memberof Spark
     * @function
     * @param {String} messageId Spark Message ID
     * @returns {Promise.<Message>} Spark Message object
     *<commit_msg>Added experimental 'after' property that can be passed to messagesGet search object per issue #11.<commit_after>const moment = require('moment');
const when = require('when');
const _ = require('lodash');
const validator = require('../validator');

/**
 * @description Message Object
 *
 * @namespace Message
 * @property {String} id - Message ID
 * @property {String} roomId - Room ID
 * @property {String} roomType - Room Type
 * @property {String} toPersonId - Person ID
 * @property {String} toPersonEmail - Person Email
 * @property {String} text - Message text
 * @property {String} markdown - Message markdown
 * @property {Array.<String>} files - Array of File URLs
 * @property {String} personId - Person ID
 * @property {String} personEmail - Person Email
 * @property {String} created - Date Message created (ISO 8601)
 * @property {Array.String} mentionedPeople - Person IDs of those mentioned in Message
 */

const Messages = (Spark) => {
  const messages = {
    /**
     * @description Returns Spark Message Objects. If 'max' is not specifed, returns all.
     *
     * @memberof Spark
     * @function
     * @param {Object} messageSearch Spark Message Search Object
     * @param {Integer} [max] Number of records to return (optional)
     * @returns {Promise.Array.<Message>} Array of Spark Message objects
     *
     * @example
     * spark.messagesGet({roomId: 'Tm90aGluZyB0byBzZWUgaGVy'}, 100)
     *   .then(messages => messages.forEach(message => console.log(message.text)))
     *   .catch(err => console.error(err));
     */
    messagesGet: (...args) => {
      const messageSearch = args.length > 0 && typeof args[0] === 'object' ? args.shift() : {};
      const maxResults = args.length > 0 && typeof args[0] === 'number' ? args.shift() : 0;

      if (!validator.isMessageSearch(messageSearch)) {
        return when.reject(new Error('invalid search'));
      }

      messageSearch.max = Spark.maxPageItems;

      // check for after property
      if (_.has(messageSearch, 'after')) {
        // increase max page items to reduce API calls for this action
        messageSearch.max = parseInt(Spark.maxPageItems, 10) * 10;
        // convert property 'after' from ISO 8601 string to epoch (ms)
        const afterDate = moment(messageSearch.after).valueOf();
        // remove unsupported SPark API property from request
        delete messageSearch.after;
        // return array of messages created after ISO 8601 date
        return Spark.request('get', 'messages', messageSearch, 0)
          .then((allMessages) => {
            const selectedMessages = _.filter(allMessages, (message) => {
              // convert property 'created' from ISO 8601 string to epoch (ms)
              const createdDate = moment(message.created).valueOf();
              // return only results where created date ms is greater than after date ms
              return (createdDate > afterDate);
            });
            return when(selectedMessages);
          });
      }

      return Spark.request('get', 'messages', messageSearch, maxResults);
    },

    /**
     * @description Return details of Spark Message by ID.
     *
     * @memberof Spark
     * @function
     * @param {String} messageId Spark Message ID
     * @returns {Promise.<Message>} Spark Message object
     *
{'fraction_non_alphanumeric': 0.12456042939107903, 'fraction_numerical': 0.0090690357208958, 'mean_word_length': 2.9764532744665195, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '190788', 'n_tokens_mistral': 1529, 'n_tokens_neox': 1458, 'n_words': 487}