/**
 *  ---------
 * |.##> <##.|  SmartCard-HSM Support Scripts
 * |#       #|
 * |#       #|  Copyright (c) 2011-2012 CardContact Software & System Consulting
 * |'##> <##'|  Andreas Schwier, 32429 Minden, Germany (www.cardcontact.de)
 *  ---------
 *
 * Consult your license package for usage terms and conditions.
 *
 * @fileoverview Personalization Client
 */

var CardTask = require("scsh/perso/CardTask").CardTask;
var File = require("scsh/file/File").File;



function Scheduler(jobs) {
	this.jobs = jobs;
	this.taskmap = [];
	this.handler = {};
}

exports.Scheduler = Scheduler;



Scheduler.prototype.handleSingle = function(readername) {
	this.term.off();
	this.card = new Card(readername);
	try	{
		var msg = scheduler.handleCard(this.card);
		print("Personalization complete: " + msg);
		this.term.green();
		if (this.printer) {
			this.printer.ejectCard();
		}
	}
	catch(e) {
		GPSystem.trace(e);
		GPSystem.trace(e.stack);
		print("Personalization failed with " + e.message);
		this.term.red();
		GPSystem.wait(200);
		this.term.off();
		GPSystem.wait(200);
		this.term.red();
		if (this.printer) {
			this.printer.rejectCard();
			var ok = Dialog.prompt("Card rejected. Continue ?");
			if (ok != "OK") {
				throw new Error("User abort");
			}
		}
	}
	delete this.card;
}



Scheduler.prototype.handleOneByOne = function() {
	while(true) {
		if (this.printer.feedCard()) {
			print("Card inserted");
		} else {
			print("Could not feed card. Stopped");
			return;
		}
		this.handleSingle(_scsh3.reader);
	}
}



Scheduler.prototype.isIgnoredReader = function(readername) {
	if ((_scsh3.reader == null) || (_scsh3.reader.length == 0)) {
		return false;
	}

	var str = "!" + readername;
	var list = _scsh3.reader.split(";");
	return list.indexOf(str) >= 0;
}



Scheduler.prototype.cardInserted = function(readername) {
	print("Inserted " + readername);

	if (this.isIgnoredReader(readername)) {
		print("Skipped reader");
		return;
	}

	if (this.mode == 2) {
		var t = this.taskmap[readername];

		if (typeof(t) != "undefined") {
			print("Reader " + readername + " already running. Ignored");
		}

		t = new CardTask(this, readername);
		this.taskmap[readername] = t;
		t.start();
	} else if (this.mode == 1) {
		if (this.card) {
			print("Personalization in progress...");
			return;
		}
		this.handleSingle(readername);
	}
}



Scheduler.prototype.cardRemoved = function(readername) {
	print("Removed " + readername);

	if (this.isIgnoredReader(readername)) {
		print("Skipped reader");
		return;
	}

	if (this.mode == 2) {
		var t = this.taskmap[readername];
		if (typeof(t) != "undefined") {
			t.stop();
			delete this.taskmap[readername];
		}
	} else {
		if (this.printer) {
			if (this.printer.feedCard()) {
				print("Card inserted");
			} else {
				print("Could not feed card. Stopped");
				Card.setCardEventListener();
			}
		}
	}
}



Scheduler.prototype.cardNotification = function(readername) {
	if (this.isIgnoredReader(readername)) {
		print("Skipped reader");
		return;
	}

	if (this.mode == 2) {
		var t = this.taskmap[readername];
		if (typeof(t) != "undefined") {
			t.notify();
		}
	} else {
		print(this.card.remoteMessage + " (" + this.card.remoteMessageId + ")");
	}
}



Scheduler.prototype.handleCard = function(card) {
	var msg = "Done";

	if (this.initializer) {
		var msg = this.initializer.handleCard(card);
	}
	if (this.personalizer) {
		var msg = this.personalizer.handleCard(card);
	}
	print(msg);

	return msg;
}



Scheduler.prototype.configureJob = function() {
	for (var n in this.job) {
		if (n == "Name") {
			continue;
		}

		var cfg = n;
		if (n == "PortalPersonalizer2") {
			n = "PortalPersonalizer";
		} else if (n == "PreIssuance") {
			n = "Initializer";
		} else if (n == "PostIssuance") {
			n = "Initializer";
		}

//		print("###Locating " + n);

		var clazz = this.handler[n];
		if (typeof(clazz) == "undefined") {
			var prefix = "";
			var f = new File(clazz + ".js");
			if (!f.exists()) {
				prefix = "scsh/perso/";
			}
			clazz = require(prefix + n)[n];
			this.handler[n] = clazz;
		}
//		print("###Type : " + clazz.type);

		this[clazz.type] = new clazz(this.job[cfg]);
		this[clazz.type].configure();
	}
}



Scheduler.prototype.selectJob = function() {
	var list = [];

	for (var i = 0; i < this.jobs.length; i++) {
		list.push(this.jobs[i].Name);
	}

	var cust = Dialog.prompt("Select job", "", list);
	if (cust == null) {
		throw new Error("User abort");
	}

	var i = list.indexOf(cust);
	this.job = this.jobs[i];

	this.configureJob();
}



Scheduler.prototype.selectMode = function() {
	var modelist = [ "Single-Shot", "Single-Card-Insert", "Multi-Card-Insert" ];

	var defsel = modelist[1];
	if (this.printer) {
		defsel = "One-by-One";
		modelist.push(defsel);
	}

	var sel = Dialog.prompt("Mode", defsel, modelist);
	if (sel == null) throw new Error("User abort");

	this.mode = modelist.indexOf(sel);

	if (this.mode != 2) {
		this.term = new AccessTerminal();
		this.term.green();
	}

	if (this.mode == 0) {
		scheduler.handleSingle(_scsh3.reader);
	} else if (this.mode == 3) {
		scheduler.handleOneByOne();
	} else {
		Card.setCardEventListener(this);
		if (this.printer) {
			if (this.printer.feedCard()) {
				print("Card inserted");
			} else {
				print("Could not start card feed");
				Card.setCardEventListener();
			}
		} else {
			print("Personalization system ready. Please insert card.");
		}
	}
}
