// ======================================================================
// DCANNOUNCE
// uTorrent/SABnzbd+ announce bot for for a DC hub
// ======================================================================

// Configuration

var dca_settings = {
	'hubip':	'127.0.0.1',
	'hubport':	411,
	'hubnick':	'DCAnnounce',
	'hubpass':	'',
	'hubshare':	0,
	
	'utip':		'10.0.0.99',
	'utport':	81,
	'utuser':	'admin',
	'utpass':	'admin',
	
	'sabhost':	'10.0.0.99',
	'sabport':	8080,
	'sabuser':	'admin',
	'sabpass':	'admin',
	'sabapikey':'cd8756e2f913ac66c02e452277157eb8',
	
	'refresh_interval': 300 // 5 * 60 seconds
};

// Code begins here

var dca_await    = dca_settings['refresh_interval'];
var dca_torrents = [];
var dca_usenet   = [];

// Ensure we're connected to the hub
function dca_checkConnection() {
	if (nmdc_connected() != 1) {
		mudc_console("Reconnecting to the hub...");
		nmdc_connect(
			dca_settings['hubip'], dca_settings['hubport'],
			dca_settings['hubnick'], dca_settings['hubpass'],
			dca_settings['hubshare']
		);
	}	
}

// Display an alert when a download is completed
function dca_alert(category, name) {
	if ( category.length && category != "*" ) {
		nmdc_say("["+category+"] \"" + name + "\" has finished downloading.");
	} else {
		nmdc_say("\"" + name + "\" has finished downloading.");
	}
}

// Returns false, or the torrent data array with id in collection
function dca_matchTorrent(id, collection) {
	for (var i = 0; i < collection.length; i++) {
		if (collection[i][0] == id) return collection[i];
	}
	return false;
}

// Returns false, or the sabnzbd data array with nzoid in collection
function dca_matchUsenet(nzoid, collection) {
	for (var i = 0; i < collection.length; i++) {
		if (collection[i]['nzo_id'] == nzoid) return collection[i];
	}
	return false;
}

// Check for newly completed torrents
function dca_updateTorrents() {
	
	var current = utorrent_torrents();
	if (! current['torrents'].length) {
		mudc_console("No torrents, or invalid server response.");
		return;
	}
	mudc_console("Got a list of " + current['torrents'].length+ " torrents.");
	
	// 0: ID, 2: Name, 4: Progress (0..1000), 11: Label
	
	for (var i = 0; i < current['torrents'].length; i++) {
		if (current['torrents'][i][4] == 1000) {
			
			// A torrent has finished. Check to see if it had finished last time
			
			var thisTime = current['torrents'][i];
			var lastTime = dca_matchTorrent(
				thisTime[0], dca_torrents['torrents']
			);
			
			if (lastTime === false || lastTime[4] != 1000) {
				
				// The torrent is either new, or wasn't finished last time
				dca_alert(thisTime[11], thisTime[2]);
			
			}
		}
	}
	
	dca_torrents = current;
}

// Check for newly completed usenet downloads
function dca_updateUsenet() {

	var current = sab_history();
	if (current === false) {
		mudc_console("No SABnzbd downloads, or invalid server response.");
		return;
	}
	mudc_console("Got a list of "+current['history']['slots'].length+" NZBs.");
	
	for (var i = 0; i < current['history']['slots'].length; i++) {
		// Check to see if this history item finished last time
		var thisTime = current['history']['slots'][i];
		var lastTime = dca_matchUsenet(
			thisTime['nzo_id'], dca_usenet['history']['slots']
		);
		
		if (lastTime === false) {
			// The torrent is in the history now, and wasn't last time we checked
			
			dca_alert(thisTime['category'], thisTime['name']);
				
		}
	}

	dca_usenet = current;
}

// Called every second
function dca_onTick() {
	dca_await++;
	if (dca_await >= dca_settings['refresh_interval']) {
		
		dca_checkConnection();	
		dca_updateTorrents();	
		dca_updateUsenet();
		
		dca_await = 0;
	}
}

function dca_onLoad() {

	// Set up connections

	utorrent_init(
		dca_settings['utip'], dca_settings['utport'],
		dca_settings['utuser'], dca_settings['utpass']
	);
	sab_init(
		dca_settings['sabhost'], dca_settings['sabport'],
		dca_settings['sabuser'], dca_settings['sabpass'],
		dca_settings['sabapikey']
	);
	dca_checkConnection();
	
	// Get initial values
	
	dca_torrents = utorrent_torrents();
	dca_usenet = sab_history();
	
	// Register timer handler
	
	_onTick.push(dca_onTick);
}

dca_onLoad();
