<commit_before>'use strict';

//var config = require('../config');

var mongoose = require('mongoose');
var _ = require('underscore');
var Schema = mongoose.Schema;
var User = require('./users');
var actionComments = require('./actionComments');
var escapeStringRegexp = require('escape-string-regexp');

var ActionSchema = new Schema({
  name: {
    type: String,
    required: true,
    unique: true
  },
  tag: {
    type: String,
    enum: 'daily onetime high-effort repeating'.split(' '),
    default: 'daily'
  },
  activation: {
    configurable: {
      type: Boolean,
      default: false
    },
    repeat: Number,
    delay: Number
  },
  description: {
    type: String,
    required: true
  },
  impact: {
    type: Number,
    min: 1,
    max: 5,
    default: 3
  },
  effort: {
    type: Number,
    min: 1,
    max: 5,
    default: 3
  },
  ratings: {
    type: Schema.Types.Mixed,
    default: {}
  },
  date: {
    type: Date,
    required: true
  },
  authorId: {
    type: Schema.Types.ObjectId,
    required: true
  }
});

var Action = mongoose.model('Action', ActionSchema);

var includeRatingStats = function(action) {
  var sum = 0;

  _.each(action.ratings, function(rating) {
    if (rating.rating) {
      sum += 1;
    }
  });

  action.numLikes = sum;
};

var includeMeanEffort = function(action) {
  var effortEstimates = [];

  // include initial effort estimate with larger weight
  for (var i = 0; i < 5; i++) {
    effortEstimates.push(action.effort);
  }

  _.each(action.ratings, function(rating) {
    if (rating.effort) {
      effortEstimates.push(rating.effort);
    }
  });

  action.effort = effortEstimates[parseInt(effortEstimates.length / 2)];
};

exports.create = function(action, cb) {
  Action.create({
    name: action.name,
    tag: action.tag,
    activation: action.activation,
    description: action.description,
    ratings: action.ratings || {},
    impact: action.impact,
    effort: action.effort,
    authorId: action.authorId,
    date: new Date()
  }, cb);
};

exports.get = function(id, user, cb) {
  Action.findOne({
    _id: id
  }, function(err, action) {
    if (err) {
      cb(err);
    } else if (!action) {
      cb('Action not found');
    } else {
      action = action.toObject();
      includeRatingStats(action);
      includeMeanEffort(action);

      // include user's rating
      if (user && action.ratings && action.ratings[user._id]) {
        action.userRating = action.ratings[user._id].rating;
      }

      // fetch number of comments to this action
      actionComments.get(id, null, null, null, function(err, aComments) {
        if (err) {
          return cb(err);
        }

        action.numComments = aComments.length;

        // fetch number of users doing this action
        User.model.find({
          $or: [
            {'actions.inProgress': {$elemMatch: {_id: id}}},
            {'actions.done': {$elemMatch: {_id: id}}}
          ]
        }, function(err, users) {
          if (err) {
            return cb(err);
          }<commit_msg>fix numUsers in action GET<commit_after>'use strict';

//var config = require('../config');

var mongoose = require('mongoose');
var _ = require('underscore');
var Schema = mongoose.Schema;
var User = require('./users');
var actionComments = require('./actionComments');
var escapeStringRegexp = require('escape-string-regexp');

var ActionSchema = new Schema({
  name: {
    type: String,
    required: true,
    unique: true
  },
  tag: {
    type: String,
    enum: 'daily onetime high-effort repeating'.split(' '),
    default: 'daily'
  },
  activation: {
    configurable: {
      type: Boolean,
      default: false
    },
    repeat: Number,
    delay: Number
  },
  description: {
    type: String,
    required: true
  },
  impact: {
    type: Number,
    min: 1,
    max: 5,
    default: 3
  },
  effort: {
    type: Number,
    min: 1,
    max: 5,
    default: 3
  },
  ratings: {
    type: Schema.Types.Mixed,
    default: {}
  },
  date: {
    type: Date,
    required: true
  },
  authorId: {
    type: Schema.Types.ObjectId,
    required: true
  }
});

var Action = mongoose.model('Action', ActionSchema);

var includeRatingStats = function(action) {
  var sum = 0;

  _.each(action.ratings, function(rating) {
    if (rating.rating) {
      sum += 1;
    }
  });

  action.numLikes = sum;
};

var includeMeanEffort = function(action) {
  var effortEstimates = [];

  // include initial effort estimate with larger weight
  for (var i = 0; i < 5; i++) {
    effortEstimates.push(action.effort);
  }

  _.each(action.ratings, function(rating) {
    if (rating.effort) {
      effortEstimates.push(rating.effort);
    }
  });

  action.effort = effortEstimates[parseInt(effortEstimates.length / 2)];
};

exports.create = function(action, cb) {
  Action.create({
    name: action.name,
    tag: action.tag,
    activation: action.activation,
    description: action.description,
    ratings: action.ratings || {},
    impact: action.impact,
    effort: action.effort,
    authorId: action.authorId,
    date: new Date()
  }, cb);
};

exports.get = function(id, user, cb) {
  Action.findOne({
    _id: id
  }, function(err, action) {
    if (err) {
      cb(err);
    } else if (!action) {
      cb('Action not found');
    } else {
      action = action.toObject();
      includeRatingStats(action);
      includeMeanEffort(action);

      // include user's rating
      if (user && action.ratings && action.ratings[user._id]) {
        action.userRating = action.ratings[user._id].rating;
      }

      // fetch number of comments to this action
      actionComments.get(id, null, null, null, function(err, aComments) {
        if (err) {
          return cb(err);
        }

        action.numComments = aComments.length;

        // fetch number of users doing this action
        var inProgressQuery = {};
        inProgressQuery['actions.inProgress.' + id] = {$exists: true};

        var doneQuery = {};
        doneQuery['actions.done.' + id] = {$exists: true};

        User.model.find({
          $or: [inProgressQuery, doneQuery]
        }, function(err, users) {
          if (err) {
            return cb(err);
          }
{'fraction_non_alphanumeric': 0.14380352237841332, 'fraction_numerical': 0.003554693811601228, 'mean_word_length': 2.4833989870568374, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, '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': '1327267', 'n_tokens_mistral': 2047, 'n_tokens_neox': 1976, 'n_words': 478}