/*
 * 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 com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
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;

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

/**
 * Encapsulates the initial message generated by a {@link ZeroProofGenerator}.
 */
public class ZeroProofInitialMessage {

    private final PublicCommitment cA0;

    private final PublicCommitment cBM;

    private final PublicCommitment[] cD;

    @JsonCreator
    public ZeroProofInitialMessage(@JsonProperty("commitmentPublicA0") final PublicCommitment cA0,
            @JsonProperty("commitmentPublicBM") final PublicCommitment cBM,
            @JsonProperty("commitmentPublicD") final PublicCommitment[] cD) {

        this.cA0 = cA0;
        this.cBM = cBM;
        this.cD = cD;
    }

    public ZeroProofInitialMessage(final PrivateCommitment cA0, final PrivateCommitment cBM,
            final PrivateCommitment[] cD) {

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

        final int length = cD.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.cD = new PublicCommitment[cD.length];
        final PublicCommitmentCalculatorProcess process = new PublicCommitmentCalculatorProcess(this.cD, cD);

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

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

    /**
     * @return Returns the cBM.
     */
    public PublicCommitment getCommitmentPublicBM() {
        return cBM;
    }

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

    @Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("ZeroProofInitialMessage [_cA0=");
		builder.append(cA0);
		builder.append(", _cBM=");
		builder.append(cBM);
		builder.append(", _cD=");
		builder.append(Arrays.toString(cD));
		builder.append("]");
		return builder.toString();
	}
}
