/*
 * 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 OV */
/* global CL */
/* global forge */
/* jshint maxlen: 6666 */

module.exports = (function() {

    'use strict';

    // Precompute a partial choice code

    var precomputePartialChoiceCode = function(serializedEncParams, serializedOption, serializedExponent) {

        // nothing to do if we already have this partial choice code

        var codesPool = OV.session('pccPool');
        if (!codesPool) { // no pool yet? 
            codesPool = [];
            OV.session('pccPool', codesPool); // create it
        } else if (codesPool[serializedOption]) { // pcc already known?
            return; // we're done
        }

        // get encryption params if not already cached

        var encryptionParms = OV.session('encParams');
        if (!encryptionParms) {
            encryptionParms = new OV.model.EncryptionParams(serializedEncParams);
            OV.session('encParams', encryptionParms);
        }

        // get exponent if not already cached

        var exponent = OV.session('maskExponent');
        if (!exponent) {
            exponent = new forge.jsbn.BigInteger(serializedExponent);
            OV.session('maskExponent', exponent); // cache it
        }

        // deserialize option

        var option = new CL.commons.mathematical.ZpGroupElement(
            new forge.jsbn.BigInteger(serializedOption),
            encryptionParms.p,
            encryptionParms.q);

        // compute and store

        var pcc = option.getElementValue().modPow(exponent, encryptionParms.p);
        codesPool[serializedOption] = pcc.toString();

    };

    var getPrecomputedPartialChoiceCodes = function() {
        return OV.session('pccPool') || [];
    };

    return {
        precomputePartialChoiceCode: precomputePartialChoiceCode,
        getPrecomputedPartialChoiceCodes : getPrecomputedPartialChoiceCodes
    };

})();
