/*
 * 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
 */
package com.scytl.products.ov.mixnet.proofs.bg.shuffle;

import java.util.List;

import com.scytl.cryptolib.mathematical.groups.impl.Exponent;
import com.scytl.products.ov.mixnet.commons.concurrent.LoopParallelizerAction;
import com.scytl.products.ov.mixnet.commons.concurrent.processor.PrivateAndPublicCommitmentProcessor;
import com.scytl.products.ov.mixnet.commons.proofs.bg.commitments.CommitmentParams;
import com.scytl.products.ov.mixnet.commons.proofs.bg.commitments.PrivateCommitment;
import com.scytl.products.ov.mixnet.commons.proofs.bg.commitments.PublicCommitment;
import com.scytl.products.ov.mixnet.commons.tools.LoopTools;
import com.scytl.products.ov.mixnet.commons.tools.LoopTools.Range;
import com.scytl.products.ov.mixnet.commons.tools.MultiExponentiation;

/**
 * Implements the parallelized mode.
 */
public class ParallelPrivateAndPublicCommitmentsGenerator implements PrivateAndPublicCommitmentsGenerator {

    /**
     * Generates private and public commitments using a pool of {@code concurrencyLevel} threads.
     *
     * @param exponents
     * @param r
     * @param m
     * @param comParams
     * @param privateCommitments
     * @param publicCommitments
     * @param limMultiExpo
     * @param concurrencyLevel
     */
    @Override
    public void generateAndSet(final Exponent[][] exponents, final Exponent[] r, final int m,
            final CommitmentParams comParams, final PrivateCommitment[] privateCommitments,
            final PublicCommitment[] publicCommitments, final MultiExponentiation limMultiExpo,
            final int concurrencyLevel) {
        // Ideally, the number of tasks should be independent from the number of
        // processors. In this case we use it this way to calculate the ranges.
        final List<Range> ranges = LoopTools.asRangesList(m, concurrencyLevel);

        final PrivateAndPublicCommitmentProcessor processor = new PrivateAndPublicCommitmentProcessor(
            privateCommitments, publicCommitments, exponents, r, comParams, limMultiExpo);

        new LoopParallelizerAction(processor, ranges).invoke();
    }
}
