/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
/* global CL */

module.exports = (function() {

    'use strict';
	
    var validateCertificateChain = function(certificateSign, certificateAuth, certificates) {
		
		var platformRootCA = OV.config()["platformRootCA"];

    	var getSubject = function(cert) {
			var cryptoX509Cert = new CL.certificates.CryptoX509Certificate(cert);
			var subject = { 
				commonName: cryptoX509Cert.getSubjectCN(), 
				organization: cryptoX509Cert.getSubjectOrg(), 
				organizationUnit: cryptoX509Cert.getSubjectOrgUnit(), 
				country: cryptoX509Cert.getSubjectCountry()
			};
			return subject;
    	};

    	var getSubjects = function(certs) {
    		var subjects = [];
    		for (var i = 0; i < certs.length; i++) {
				var subject = getSubject(certs[i]);
				subjects.push(subject);
			}
			return subjects;
    	};

		var validateChain = function(cert, certs, rootCert, keyType) {

	    	var chain = {
				leaf: {
					pem: cert,
					keyType: keyType,
					subject: getSubject(cert)
				}, 
				certificates: {
					pems: certs,
					subjects: getSubjects(certs)
				},
				root: rootCert
	    	};

	        var validationResult = CL.certificates.service.validateX509CertificateChain(chain);

			for (var i = 0; i < validationResult.length; i++) {
	        	if (validationResult[i].length !== 0) {
	        		throw new Error('Certificate chain validation: [' + 
	        			chain.leaf.subject.commonName + ', ' + 
	        			chain.certificates.subjects + ', ' + 
	        			getSubject(rootCert).commonName +
	        			'] failed: ' + validationResult);
	        	}
	        }
		};

		// [Election Root CA]
		validateChain(certificates.electionRootCA, [], certificates.electionRootCA, 'CA');

		// [Authentication Token Certificate, Services CA, Election Root CA]
		validateChain(certificates.authenticationTokenSignerCert, [certificates.servicesCA], 
			certificates.electionRootCA, 'Sign');

		// [AB Certificate, TENANT CA, Platform Root CA]
		validateChain(certificates.adminBoard, [certificates.tenantCA],
			platformRootCA, 'Sign');

		// [Credentials CA, Election Root CA]
		validateChain(certificates.credentialsCA, [], certificates.electionRootCA, 'CA');

		// [CredentialID Signing Certificate, Credentials CA, Election Root CA]
		validateChain(certificateSign, [certificates.credentialsCA], certificates.electionRootCA, 'Sign');

		// [CredentialID Authentication Certificate, Credentials CA, Election Root CA]
		validateChain(certificateAuth, [certificates.credentialsCA], certificates.electionRootCA, 'Sign');
    };    

    return validateCertificateChain;
})();
