<commit_before>/**
 * Created by <NAME> on 8/17/15.
 */
"use strict";

var async = require('async'),
	JiraApi = require('jira').JiraApi,
	JiraFacade,
	jira;

module.exports = JiraFacade = function (config) {
	if (!config.protocol || !config.host || !config.username || !config.password) {
		throw new Error('protocol, host, username and password are required.');
	}
	if (!config.port) {
		config.port = (config.protocol.toLowerCase() === 'https') ? 443 : 80;
	}
	config.apiVersion = config.apiVersion || 2;
	this.jira = jira = new JiraApi(config.protocol, config.host, config.port, config.username, config.password, config.apiVersion);
};

// ********************************************************************
// Instance Methods
// ********************************************************************
(function () {
	this.createIssue = function (options, callback) {
		var that = this,
			payload = {};
		async.waterfall([
			// get Priority
			function (next) {
				that.getPriorityByName(options.priority, handleGetPriority(payload, next));
			},
			// get project, issueType, versions and components
			function (payload, next) {
				jira.getProject(options.project, handleGetProject(options, payload, next));
			},
			// create Issue
			function (payload, next) {
				var issueOptions = createIssueOptions(payload, options);

				jira.addNewIssue(issueOptions, function (err, issue) {
					if (err) {
						return next(err);
					} else {
						next(null, issue);
					}
				});
			}
		], function (err, payload) {
			callback(err, payload);
		});
	};

	this.getVersionByName = function (project, versionName, callback) {
		jira.getVersions(project, filterVersionsByName(versionName, callback));
	};

	this.getPriorityByName = function (priorityName, callback) {
		jira.listPriorities(filterPrioritiesByName(priorityName, callback));
	};

	this.getPriorityById = function (priorityId, callback) {
		priorityId = parseInt(priorityId);
		// if it is not a number, error
		if (!isNumeric(priorityId)) {
			callback('Priority ID must be numeric.');
			return;
		}

		jira.listPriorities(filterPrioritiesById(priorityId, callback));
	};

	this.getIssueTypeByName = function (issueTypeName, callback) {
		if (!issueTypeName) {
			return callback('Issue Type Name must be a non-zero length string.');
		}
		jira.listIssueTypes(filterIssueTypesByName(issueTypeName, callback));
	};

	this.addWatcher = function (issueKey, username, callback) {

		var options = {
			rejectUnauthorized: this.jira.strictSSL,
			uri: this.jira.makeUri('/issue/' + issueKey + '/watchers'),
			method: 'POST',
			followAllRedirects: true,
			json: true,
			body: JSON.stringify(username)
		};

		this.jira.doRequest(options, function (error, response) {
			if (error) {
				return callback(error);
			}

			if (response.statusCode === 404) {
				return callback('Invalid URL');
			}

			if (response.statusCode !== 204) {
				return callback(response.statusCode + ': Unable to connect to JIRA to add user as watcher.');
			}

		});

	};

	this.addWatchersToIssue = this.addWatcher.bind(this);

}.call(JiraFacade.prototype));

// ********************************************************************
// Utility Methods and Handlers
// ********************************************************************
function getComponentsFromProject(componentNames, project) {
	return getItemsFromProject(componentNames, project, 'component');
}

function getVersionsFromProject(versionNames, project) {
	return getItemsFromProject(versionNames, project, 'version');
}

function getItemsFromProject(itemNames, project, itemType, required) {
	if ((typeof itemNames).toLowerCase() === "string") {
		itemNames = [itemNames];
	}
	if (!Array.isArray(itemNames)) {
		throw Error('Item Names argument must be a ' + itemType + ' name string or an array of ' + itemType + ' name strings');<commit_msg>Fix issue of not having a callback on success of addWatcher<commit_after>/**
 * Created by <NAME> on 8/17/15.
 */
"use strict";

var async = require('async'),
	JiraApi = require('jira').JiraApi,
	JiraFacade,
	jira;

module.exports = JiraFacade = function (config) {
	if (!config.protocol || !config.host || !config.username || !config.password) {
		throw new Error('protocol, host, username and password are required.');
	}
	if (!config.port) {
		config.port = (config.protocol.toLowerCase() === 'https') ? 443 : 80;
	}
	config.apiVersion = config.apiVersion || 2;
	this.jira = jira = new JiraApi(config.protocol, config.host, config.port, config.username, config.password, config.apiVersion);
};

// ********************************************************************
// Instance Methods
// ********************************************************************
(function () {
	this.createIssue = function (options, callback) {
		var that = this,
			payload = {};
		async.waterfall([
			// get Priority
			function (next) {
				that.getPriorityByName(options.priority, handleGetPriority(payload, next));
			},
			// get project, issueType, versions and components
			function (payload, next) {
				jira.getProject(options.project, handleGetProject(options, payload, next));
			},
			// create Issue
			function (payload, next) {
				var issueOptions = createIssueOptions(payload, options);

				jira.addNewIssue(issueOptions, function (err, issue) {
					if (err) {
						return next(err);
					} else {
						next(null, issue);
					}
				});
			}
		], function (err, payload) {
			callback(err, payload);
		});
	};

	this.getVersionByName = function (project, versionName, callback) {
		jira.getVersions(project, filterVersionsByName(versionName, callback));
	};

	this.getPriorityByName = function (priorityName, callback) {
		jira.listPriorities(filterPrioritiesByName(priorityName, callback));
	};

	this.getPriorityById = function (priorityId, callback) {
		priorityId = parseInt(priorityId);
		// if it is not a number, error
		if (!isNumeric(priorityId)) {
			callback('Priority ID must be numeric.');
			return;
		}

		jira.listPriorities(filterPrioritiesById(priorityId, callback));
	};

	this.getIssueTypeByName = function (issueTypeName, callback) {
		if (!issueTypeName) {
			return callback('Issue Type Name must be a non-zero length string.');
		}
		jira.listIssueTypes(filterIssueTypesByName(issueTypeName, callback));
	};

	this.addWatcher = function (issueKey, username, callback) {

		var options = {
			rejectUnauthorized: this.jira.strictSSL,
			uri: this.jira.makeUri('/issue/' + issueKey + '/watchers'),
			method: 'POST',
			followAllRedirects: true,
			json: true,
			body: JSON.stringify(username)
		};

		this.jira.doRequest(options, function (error, response) {
			if (error) {
				return callback(error);
			}

			if (response.statusCode === 404) {
				return callback('Invalid URL');
			}

			if (response.statusCode !== 204) {
				return callback(response.statusCode + ': Unable to connect to JIRA to add user as watcher.');
			}
			return callback(null, 'Successfully added ' + username + ' as a watcher.');
		});

	};

	this.addWatchersToIssue = this.addWatcher.bind(this);

}.call(JiraFacade.prototype));

// ********************************************************************
// Utility Methods and Handlers
// ********************************************************************
function getComponentsFromProject(componentNames, project) {
	return getItemsFromProject(componentNames, project, 'component');
}

function getVersionsFromProject(versionNames, project) {
	return getItemsFromProject(versionNames, project, 'version');
}

function getItemsFromProject(itemNames, project, itemType, required) {
	if ((typeof itemNames).toLowerCase() === "string") {
		itemNames = [itemNames];
	}
	if (!Array.isArray(itemNames)) {
		throw Error('Item Names argument must be a ' + itemType + ' name string or an array of ' + itemType + ' name strings');
{'fraction_non_alphanumeric': 0.1976773864216437, 'fraction_numerical': 0.004338948443083206, 'mean_word_length': 4.519014084507043, 'pattern_counts': {'":': 0, '<': 5, '<?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': '4563233', 'n_tokens_mistral': 2591, 'n_tokens_neox': 2266, 'n_words': 547}