/*
 * 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 ReductionProofGenerator}.
 */
public class MultiExponentiationReductionInitialMessage {

    private final PublicCommitment[] cb;

    private final Ciphertext[] E;

    @JsonCreator
    public MultiExponentiationReductionInitialMessage(@JsonProperty("commitmentPublicB") final PublicCommitment[] cb,
            @JsonProperty("ciphertextsE") final Ciphertext[] E) {
        this.cb = cb;
        this.E = E;
    }

    public MultiExponentiationReductionInitialMessage(final PrivateCommitment[] cb, final Ciphertext[] E) {

    	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 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("MultiExponentiationReductionInitialMessage [_cb=");
        builder.append(Arrays.toString(cb));
        builder.append(", _E=");
        builder.append(Arrays.toString(E));
        builder.append("]");
        return builder.toString();
    }
}
