<commit_before>'use strict';


// Variables.
var fs = require('fs'),
	path = require('path'),
	_ = require('underscore'),
	async = require('async'),
	util = require('util'),
	csv = require('csv'),
	dateformat = require('dateformat');

var args = process.argv.slice(2);

if( args.length < 2 ) {
	showHelp();
}

var lastMonthPath = path.resolve( __dirname, args[0] ),
	requestsPath = path.resolve( __dirname, args[1] ),
	date = new Date();
date.setMonth( date.getMonth() - 1 );

var reportPath = 'report-' + dateformat( date, 'mm-yyyy' ) + '.txt';

if( args.length === 3 ) {
	reportPath = path.resolve( __dirname, args[2] );
}

var users = [];

fs.readFile( lastMonthPath, parseReport );


/**
 * PARSE FUNCTIONS
 */

/**
 * Parses last month's report.
 * @param  {string} data The file data.
 * @return {void}
 */
function parseReport(err, data) {
	if( err ) {
		process.stderr.write('ERROR: Could not read file "' + lastMonthPath + '".\n');
		process.exit(0);
	}

	write('Parsing last month\'s data.');
	data = data.toString('utf-8');

	// Parse users.
	async.each( data.split('Member Name: '), function(string, done) {
		var user = parseUser(string);
		if(user) {
			users.push(user);
		}
		done();
	});

	write( 'Got ' + users.length + ' members:' );
	write( '  ' + getExpired(users).length + ' expired.' );
	write( '  ' + getTrial(users).length + ' trial.' );

	var columns = [ 'name', 'category', 'amount', 'backdate', 'description' ];

	fs.createReadStream( requestsPath ).pipe( csv.parse( { columns: columns }, parseRequests ) );
}


/**
 * Parses requests file to file awards.
 * @param  {object} err    Error object.
 * @param  {string} output The parsed object.
 * @return {void}
 */
function parseRequests(err, output) {
	if( err ) {
		process.stderr.write('ERROR: Could not read file "' + requestsPath + '".\n');
		process.exit(0);
	}

	write( 'Found ' + output.length + ' awards.' );

	var name = '',
		categoryMap = {
			'Administration (80 max)': 'admin',
			'Non-Administrative Game Support (50 max)': 'nonadmin',
			'Social/Non-Game Support (50 max)': 'social',
			'Miscellaneous': 'misc'
		},
		capMap = {
			'admin': 80,
			'nonadmin': 50,
			'social': 50,
			'misc': -1
		};

	var findUser = function (item, callback) {
		if( item.first === name[1] && item.last === name[0] ) {
			callback(true);
		}
		callback(false);
	};

	async.each( output, function(row, done) {
		name = row.name.split(', ');

		async.detect( users, findUser, function(result) {
			if( undefined !== result ) {
				result.awards.push({
					category: categoryMap[row.category],
					amount: parseInt( row.amount ),
					description: row.description,
					backdate: ( '' === row.backdate || dateformat(date, 'mmmm') === row.backdate ) ? false : row.backdate
				});

				result.amount += parseInt( row.amount );
			}

			done();
		});
	});

	async.each( users, function(user, done) {
		user.awards = _.groupBy( user.awards, 'category' );

		_.each( user.awards, function(val, key) {
			var total = _.reduce( val, function( memo, val ) {
				return memo + val.amount;
			}, 0);
			
			// If we have overcap, reduce the totals.
			if( capMap[key] < total && -1 !== capMap[key] ) {
				write( 'Notice: ' + user.first + ' ' + user.last + ' has ' + total + ' prestige in ' + key + '.' );
				var difference = total - capMap[ key ],
					remaining = difference,
					index = 1;

				while ( remaining > 0 ) {
					var last = _.last( val, index )[0];
					last.origAmount = last.amount;
					last.amount = Math.max( 0, last.amount - difference );
					remaining -= last.amount;
					console.log( last );
					write( 'Reduced award for ' + last.description + ' to ' + last.amount + ' from ' + last.origAmount + '.' );
					index++;
				}

				// Reduce the total.
				user.amount -= difference;
			}
		});

		done();
	});

	// Parses the data and creates the template.
	var report = getTemplate(users);
	writeReport(report);
}


/**
 * Writes the report to disk.
 * @param  {string} report The report.
 * @return {void}
 */
function writeReport(report) {
	fs.writeFile( reportPath, report, function(err) {
		if( err ) {
			process.stderr.write('ERROR: Could not write file "' + reportPath + '".\n');
			process.exit(0);
		} else {<commit_msg>Got rid of debug message, added additional message.<commit_after>'use strict';


// Variables.
var fs = require('fs'),
	path = require('path'),
	_ = require('underscore'),
	async = require('async'),
	util = require('util'),
	csv = require('csv'),
	dateformat = require('dateformat');

var args = process.argv.slice(2);

if( args.length < 2 ) {
	showHelp();
}

var lastMonthPath = path.resolve( __dirname, args[0] ),
	requestsPath = path.resolve( __dirname, args[1] ),
	date = new Date();
date.setMonth( date.getMonth() - 1 );

var reportPath = 'report-' + dateformat( date, 'mm-yyyy' ) + '.txt';

if( args.length === 3 ) {
	reportPath = path.resolve( __dirname, args[2] );
}

var users = [];

fs.readFile( lastMonthPath, parseReport );


/**
 * PARSE FUNCTIONS
 */

/**
 * Parses last month's report.
 * @param  {string} data The file data.
 * @return {void}
 */
function parseReport(err, data) {
	if( err ) {
		process.stderr.write('ERROR: Could not read file "' + lastMonthPath + '".\n');
		process.exit(0);
	}

	write('Parsing last month\'s data.');
	data = data.toString('utf-8');

	// Parse users.
	async.each( data.split('Member Name: '), function(string, done) {
		var user = parseUser(string);
		if(user) {
			users.push(user);
		}
		done();
	});

	write( 'Got ' + users.length + ' members:' );
	write( '  ' + getExpired(users).length + ' expired.' );
	write( '  ' + getTrial(users).length + ' trial.' );

	var columns = [ 'name', 'category', 'amount', 'backdate', 'description' ];

	fs.createReadStream( requestsPath ).pipe( csv.parse( { columns: columns }, parseRequests ) );
}


/**
 * Parses requests file to file awards.
 * @param  {object} err    Error object.
 * @param  {string} output The parsed object.
 * @return {void}
 */
function parseRequests(err, output) {
	if( err ) {
		process.stderr.write('ERROR: Could not read file "' + requestsPath + '".\n');
		process.exit(0);
	}

	write( 'Found ' + output.length + ' awards.' );

	var name = '',
		count = 0,
		categoryMap = {
			'Administration (80 max)': 'admin',
			'Non-Administrative Game Support (50 max)': 'nonadmin',
			'Social/Non-Game Support (50 max)': 'social',
			'Miscellaneous': 'misc'
		},
		capMap = {
			'admin': 80,
			'nonadmin': 50,
			'social': 50,
			'misc': -1
		};

	var findUser = function (item, callback) {
		if( item.first === name[1] && item.last === name[0] ) {
			callback(true);
		}
		callback(false);
	};

	async.each( output, function(row, done) {
		name = row.name.split(', ');

		async.detect( users, findUser, function(result) {
			if( undefined !== result ) {
				result.awards.push({
					category: categoryMap[row.category],
					amount: parseInt( row.amount ),
					description: row.description,
					backdate: ( '' === row.backdate || dateformat(date, 'mmmm') === row.backdate ) ? false : row.backdate
				});

				result.amount += parseInt( row.amount );
			}

			count++;
			done();
		});
	});

	async.each( users, function(user, done) {
		user.awards = _.groupBy( user.awards, 'category' );

		_.each( user.awards, function(val, key) {
			var total = _.reduce( val, function( memo, val ) {
				return memo + val.amount;
			}, 0);
			
			// If we have overcap, reduce the totals.
			if( capMap[key] < total && -1 !== capMap[key] ) {
				write( 'Notice: ' + user.first + ' ' + user.last + ' has ' + total + ' prestige in ' + key + '.' );
				var difference = total - capMap[ key ],
					remaining = difference,
					index = 1;

				while ( remaining > 0 ) {
					var last = _.last( val, index )[0];
					last.origAmount = last.amount;
					last.amount = Math.max( 0, last.amount - difference );
					remaining -= last.amount;
					write( '  Reduced award for ' + last.description + ' to ' + last.amount + ' from ' + last.origAmount + '.' );
					index++;
				}

				// Reduce the total.
				user.amount -= difference;
			}
		});

		done();
	});

	write( 'Awarded ' + count + ' awards.' );

	// Parses the data and creates the template.
	var report = getTemplate(users);
	writeReport(report);
}


/**
 * Writes the report to disk.
 * @param  {string} report The report.
 * @return {void}
 */
function writeReport(report) {
	fs.writeFile( reportPath, report, function(err) {
		if( err ) {
			process.stderr.write('ERROR: Could not write file "' + reportPath + '".\n');
			process.exit(0);
		} else {
{'fraction_non_alphanumeric': 0.1831712176256885, 'fraction_numerical': 0.007617485058010079, 'mean_word_length': 3.1167390255668113, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, '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': '1941581', 'n_tokens_mistral': 3278, 'n_tokens_neox': 2875, 'n_words': 744}