/*
 * 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.commons.beans.proofs;

import java.util.Arrays;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.scytl.cryptolib.elgamal.cryptoapi.Ciphertext;
import com.scytl.products.ov.mixnet.commons.concurrent.LoopParallelizerAction;
import com.scytl.products.ov.mixnet.commons.concurrent.processor.PublicCommitmentCalculatorProcess;
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;

/**
 * This class encapsulates the initial message that is generated by the {@link BasicInitialMessageGenerator}.
 */
public class MultiExponentiationBasicProofInitialMessage {

    private final PublicCommitment cA0;

    private final PublicCommitment[] cB;

    private final Ciphertext[] E;

    @JsonCreator
    public MultiExponentiationBasicProofInitialMessage(@JsonProperty("commitmentPublicA0") final PublicCommitment cA0,
            @JsonProperty("commitmentPublicB") final PublicCommitment[] cB,
            @JsonProperty("ciphertextsE") final Ciphertext[] E) {
        this.cA0 = cA0;
        this.cB = cB;
        this.E = E;
    }

    public MultiExponentiationBasicProofInitialMessage(final PrivateCommitment cA0, final PrivateCommitment[] cB,
            final Ciphertext[] E) {

    	this.cA0 = cA0.makePublicCommitment();
    	this.E = E;

        final int length = cB.length;
        // 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(length, 1);

        this.cB = new PublicCommitment[cB.length];
        final PublicCommitmentCalculatorProcess process = new PublicCommitmentCalculatorProcess(this.cB, cB);

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

    /**
     * @return Returns the cA0.
     */
    public PublicCommitment getCommitmentPublicA0() {
        return cA0;
    }

    /**
     * @return Returns the cB.
     */
    public PublicCommitment[] getCommitmentPublicB() {
        return cB;
    }

    /**
     * @return Returns the e.
     */
    public Ciphertext[] getCiphertextsE() {
        return E;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("MultiExponentiationBasicProofInitialMessage [_cA0=");
        builder.append(cA0);
        builder.append(", _cB=");
        builder.append(Arrays.toString(cB));
        builder.append(", _E=");
        builder.append(Arrays.toString(E));
        builder.append("]");
        return builder.toString();
    }
}
