/**
 *  ---------
 * |.##> <##.|  Open Smart Card Development Platform (www.openscdp.org)
 * |#       #|
 * |#       #|  Copyright (c) 1999-2022 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 A service request creating and managing a TrustCenter
 */

var ServiceRequestModel	= require('pki-as-a-service/service/ServiceRequestModel').ServiceRequestModel;
var SubjectDAO		= require('scsh/pki-db/db/SubjectDAO').SubjectDAO;



/**
 * Data model for creating a trust center
 *
 * @constructor
 */
function CreateESTServerRequestModel(service, bo) {
	ServiceRequestModel.call(this, service, bo);
}

CreateESTServerRequestModel.prototype = Object.create(ServiceRequestModel.prototype);
CreateESTServerRequestModel.constructor = CreateESTServerRequestModel;

exports.CreateESTServerRequestModel = CreateESTServerRequestModel;



CreateESTServerRequestModel.prototype.getForm = function(user) {
	if (this.form == undefined) {
		var editable = (user.id == this.getOriginatorId()) &&
			((this.bo.lifecycle == ServiceRequestModel.LIFECYCLE_NEW) ||
			(this.bo.lifecycle == ServiceRequestModel.LIFECYCLE_EDIT) ||
			(this.bo.lifecycle == ServiceRequestModel.LIFECYCLE_SUBMIT));

		var lcPriv = { id: SubjectDAO.LIFECYCLE_PRIVATE, value: "Private" };
		var lcPub = { id: SubjectDAO.LIFECYCLE_PUBLIC, value: "Public" };
		var lifecycles = [lcPriv, lcPub];
		var editableLC = true
		if (this.bo.lifecycle <= ServiceRequestModel.LIFECYCLE_PRODUCE) {
				GPSystem.log(GPSystem.DEBUG, module.id, "this.model.lc="+this.model.lc);
			if (this.model.lc == SubjectDAO.LIFECYCLE_PUBLIC) {
				GPSystem.log(GPSystem.DEBUG, module.id, "public");
				lcPub.selected = true;
			} else {
				GPSystem.log(GPSystem.DEBUG, module.id, "private");
				lcPriv.selected = true;
			}
		} else {
			var estServer = this.getRecipient();
			var lcSusp = { id: SubjectDAO.LIFECYCLE_SUSPENDED, value: "Suspended" };
			var lifecycles = [lcPriv, lcPub, lcSusp];

			if (estServer.getLifeCycle() == SubjectDAO.LIFECYCLE_PUBLIC) {
				lcPub.selected = true;
			} else if (estServer.getLifeCycle() == SubjectDAO.LIFECYCLE_SUSPENDED) {
				lcSusp.selected = true;
			} else {
				lcPriv.selected = true;
			}
		}

		this.form = [{
			id: "subjectData",
			legend: "msg.estsubject.subjectData",
			fields: [
				{ id: "name", label: "msg.estsubject.name", type: "text", size: 50, required: true, editable: editable, value: (this.model.name ? this.model.name : "") },
				{ id: "lc", label: "msg.estsubject.lc", type: "select", editable: editableLC, value: lifecycles }
			]},
		];

		if (this.getRecipientId()) {
			var tokenDAO = this.service.daof.getTokenDAO();
			var tokenList = tokenDAO.getTokenListBySubjectId(this.getRecipientId());

			if (tokenList.length > 0) {
				var selectionList = [];
				for (var i = 0; i < tokenList.length; i++) {
					selectionList.push( { id: i, value: tokenList[i].path, selected: this.model.token == i } );
				}

				this.form[0].fields.push( { id: "token", label: "msg.casubject.token", type: "select", multiselect: true, editable: true, required: false, value: selectionList } );
			}
		}
	}

	return this.form;
}



CreateESTServerRequestModel.prototype.getActionList = function(user) {
	if (this.actionList != undefined) {
		return this.actionList;
	}

	this.actionList = [];

	if (user.id == this.getOriginatorId()) {
		if ((this.bo.lifecycle == ServiceRequestModel.LIFECYCLE_NEW) ||
			(this.bo.lifecycle == ServiceRequestModel.LIFECYCLE_EDIT)) {
			this.actionList.push("action.save");
		}

		if (this.bo.lifecycle == ServiceRequestModel.LIFECYCLE_EDIT) {
			this.actionList.push("action.submit");
		}

		if (this.bo.lifecycle == ServiceRequestModel.LIFECYCLE_INUSE ||
			this.bo.lifecycle == ServiceRequestModel.LIFECYCLE_SUSPENDED) {
			this.actionList.push("action.estsubject.changeMode");
		}
	}

	return this.actionList;
}



CreateESTServerRequestModel.prototype.perform = function(user, action) {
	GPSystem.log(GPSystem.DEBUG, module.id, "perform(" + user.id + "," + action + ")");

	var actionList = this.getActionList(user);

	if (actionList.indexOf(action) == -1) {
		GPSystem.log(GPSystem.DEBUG, module.id, "action list :" + actionList);
		throw new GPError(module.id, GPError.INVALID_DATA, 0, "Action " + action + " unknown");
	}

	switch(action) {
		case "action.save":
		case "action.estsubject.changeMode":
			this.save()
			break;
		case "action.submit":
			this.createSubject(user);
			break;
	}

	this.commit(user.id);
	return true;
}



CreateESTServerRequestModel.prototype.checkSize = function(fld, val) {
	if (val.length > fld.size) {
		fld.message = "You can use at most " + fld.size + " characters";
		return false;
	}
	return true;
}



CreateESTServerRequestModel.prototype.checkName = function(fld, val) {
	if (val.match(/[A-Za-z0-9._+-]+/) == null) {
		return false;
	}

	var subjectDAO = this.service.daof.getSubjectDAO();
	var subject = subjectDAO.getSubjectByTypeAndName(SubjectDAO.TYPE_EST_Server, val);

	if (subject) {
		fld.message = "An EST Server with that name does already exist";
		return false;
	}

	return true;
}



CreateESTServerRequestModel.prototype.updateModel = function(fld, val) {
	GPSystem.log(GPSystem.DEBUG, module.id, "updateModel(" + fld.id + "," + val + ")");

	switch(fld.id) {
		case "name":
			if (!this.checkSize(fld, val)) {
				return false;
			}
			if (!this.checkName(fld, val)) {
				return false;
			}
	}

	this.model[fld.id] = val;
	return true;
}



CreateESTServerRequestModel.prototype.save = function() {
	var commitChanges = false;

	if (this.getLifeCycle() == ServiceRequestModel.LIFECYCLE_NEW) {
		this.setLifeCycle(ServiceRequestModel.LIFECYCLE_EDIT);
		this.setStatusInfo("Name entered");
		commitChanges = true;
	}

	commitChanges |= this.updateDetails(this.model.name);

	if (this.getRecipientId()) {
		var isNewLC = this.getRecipient().setLifeCycle(this.model.lc);

		if (this.model.lc == SubjectDAO.LIFECYCLE_SUSPENDED && isNewLC) {
			GPSystem.log(GPSystem.DEBUG, module.id,"Suspend...");
			this.setLifeCycle(ServiceRequestModel.LIFECYCLE_SUSPENDED);
			this.setStatusInfo("EST-Server suspended");
		} else if (isNewLC && (this.bo.lifecycle == ServiceRequestModel.LIFECYCLE_SUSPENDED)) { // lifecycle public or private
			GPSystem.log(GPSystem.DEBUG, module.id,"Resume...");
			this.setLifeCycle(ServiceRequestModel.LIFECYCLE_INUSE);
			this.setStatusInfo("EST-Server enabled");
		} else if (this.model.lc == SubjectDAO.LIFECYCLE_PRIVATE && isNewLC) {
			this.setStatusInfo("EST-Server set to private operation mode");
		} else if (this.model.lc == SubjectDAO.LIFECYCLE_PUBLIC && isNewLC) {
			this.setStatusInfo("EST-Server set to private operation mode");
		} else {
			this.setStatusInfo("Operation mode hasn't changed");
		}

		commitChanges |= isNewLC
	}

	return commitChanges;
}



CreateESTServerRequestModel.prototype.createSubject = function(user) {
	GPSystem.log(GPSystem.DEBUG, module.id, "Create ESTServer subject");

	if (this.getRecipientId()) {
		GPSystem.log(GPSystem.DEBUG, module.id, "Subject already created");
		return;
	}

	var content = {
		trustCenter: this.model.trustCenter
	};

	var subjectDAO = this.service.daof.getSubjectDAO();
	var trustCenter = subjectDAO.getSubject(this.model.trustCenter);

	var template = {
		name: this.model.name,
		type: SubjectDAO.TYPE_EST_Server,
		lifecycle: this.model.lc,
		managedByRoleId: trustCenter.managedByRoleId,
		content: JSON.stringify(content, null, '\t')
	}

	var subject = subjectDAO.newSubject(template);

	var srDAO = this.service.daof.getServiceRequestDAO();
	srDAO.updateRecipientId(this.bo, subject);

	this.updateDetails(this.model.name);
	this.setLifeCycle(ServiceRequestModel.LIFECYCLE_INUSE);
	this.setStatusInfo("EST-Server Subject created");
}
