/**
 *  ---------
 * |.##> <##.|  Open Smart Card Development Platform (www.openscdp.org)
 * |#       #|
 * |#       #|  Copyright (c) 1999-2006 CardContact Software & System Consulting
 * |'##> <##'|  Andreas Schwier, 32429 Minden, Germany (www.cardcontact.de)
 *  ---------
 *
 *  This file is part of OpenSCDP.
 *
 *  OpenSCDP is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  OpenSCDP is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with OpenSCDP; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * @fileoverview Plug-In
 */


/**
 * Create a plug-in instance
 *
 * @constructor
 * @class A plug-in example
 * @param {KeyManager] km the associated key manager
 */
function PortalConnector(km) {
	this.km = km;
}

// All plug-ins must export a symbol "Plugin"
exports.Plugin = PortalConnector;

PortalConnector.USE_TOKEN_ACTION = "Connect to Portal";
PortalConnector.RELEASE_TOKEN_ACTION = "Release Portal Token";



/**
 * Add an entry to the context menu associated with the device entry in the outline
 *
 * @param {String[]} contextMenu the list of entries in the context menu
 * @param {Boolean} isInitialized the device is initialized
 * @param {Number} authenticationState the status returned in the last authentication query (SW1/SW2)
 */
PortalConnector.prototype.addDeviceContextMenu = function(contextMenu, isInitialized, authenticationState) {
	if (isInitialized) {
		contextMenu.push(PortalConnector.USE_TOKEN_ACTION);
	}
}



/**
 * Use the current token as management token
 *
 */
PortalConnector.prototype.useAsPortalConnector = function() {

	var url = this.km.sc.getProvisioningURL();

	if (!url) {
		url = "https://www.pki-as-a-service.net/rt/hsm";
	}

	url = Dialog.prompt("Connect to ", url);
	if (!url) {
		return;
	}

	var session = new PortalSession(this.km.sc, this.km.id, url);

	var readerName = this.km.sc.card.readerName;
	this.km.cardRemoved(readerName);
	this.km.autoInsert = false;

	var rl = [];
	if (_scsh3.reader) {
		var rl = _scsh3.reader.split(";");
	}

	if (rl.indexOf("!" + readerName) == -1) {
		rl.push("!" + readerName);
		_scsh3.reader = rl.join(";");
	}

	this.km.setCardRemovedListener(readerName, session);
	session.task.start();
	print("See Tasks tab for portal token");
}



/**
 * Handle action triggered from the outline context menu
 *
 * @param {Outline} source the source outline node of this action
 * @param {String} action the action selected from the context menu
 * @type Boolean
 * @return true if the action was handled
 */
PortalConnector.prototype.actionListener = function(source, action) {
	switch(action) {
		case PortalConnector.USE_TOKEN_ACTION:
			this.useAsPortalConnector();
			return true;
	}
	return false;
}



PortalConnector.prototype.toString = function() {
	return "Portal Connector Plugin";
}



function PortalSession(sc, id, url) {
	this.sc = sc;
	this.id = id;
	this.url = url;

	this.task = new Task(this);
	this.task.setContextMenu([ PortalConnector.RELEASE_TOKEN_ACTION ]);
}



PortalSession.prototype.run = function() {
	GPSystem.trace("Connected");
	this.sc.card.allowCardSpecificRemoteUpdateService(true);

	try	{
		this.sc.card.remoteUpdate(this.url);
		this.sc.logout();
		this.sc.card.close();
	}
	catch(e) {
		print("Connection failed : " + e.message);
	}

	var rl = [];
	if (_scsh3.reader) {
		var rl = _scsh3.reader.split(";");
	}

	var i = rl.indexOf("!" + this.sc.card.readerName);
	if (i >= 0) {
		rl.splice(i);
		_scsh3.reader = rl.join(";");
	}

	GPSystem.trace("Disconnected");
	this.task.disposeAtExit = true;
//	this.task.dispose();
}



PortalSession.prototype.actionListener = function(source, action) {
	switch(action) {
		case PortalConnector.RELEASE_TOKEN_ACTION:
			this.sc.card.cancelRemoteUpdate();
			return true;
	}
	return false;
}



PortalSession.prototype.cardRemoved = function() {
	print("Card removed");
	this.sc.card.cancelRemoteUpdate();
}



PortalSession.prototype.toString = function() {
	return "Portal-Token " + this.id + " connected to " + this.url;
}
