/*
 * 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.zero;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.Before;
import org.junit.Test;

import com.scytl.cryptolib.mathematical.groups.impl.Exponent;
import com.scytl.products.ov.mixnet.commons.beans.proofs.ZeroProofAnswer;
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.CommitmentTools;
import com.scytl.products.ov.mixnet.commons.tools.ExponentTools;
import com.scytl.products.ov.mixnet.commons.tools.MatrixArranger;
import com.scytl.products.ov.mixnet.commons.tools.RandomOracleHash;
import com.scytl.products.ov.mixnet.proofs.bg.BasicProofsInitializer;
import com.scytl.products.ov.mixnet.proofs.bg.hadamard.HadamardProductProofGenerator;
import com.scytl.products.ov.mixnet.proofs.bg.product.ProductProofGenerator;
import com.scytl.products.ov.mixnet.proofs.bg.shuffle.ShuffleProofGenerator;
import com.scytl.products.ov.mixnet.proofs.bg.state.MapBasedHarvester;
import com.scytl.products.ov.mixnet.proofs.bg.state.StateHarvester;

public class ParallelZeroProofGeneratorTest extends BasicProofsInitializer {

    private final StateHarvester _harvester = new MapBasedHarvester();

    ParallelZeroProofGenerator _sut;

    @Before
    public void initHarvester() {

        _harvester.collect(ShuffleProofGenerator.Produced.RANDOM_ORACLE, new RandomOracleHash(q));

        final Exponent[][] exponents =
            MatrixArranger.transformPermutationToExponentMatrix(getMockedPermutation(), q, m, n);

        final PrivateCommitment[] mockedPrivateCommitments = getMockedPrivateCommitments(exponents);
        final PublicCommitment[] mockedPublicCommitments = CommitmentTools.makePublic(mockedPrivateCommitments);

        _harvester.collect(ProductProofGenerator.Produced.PRIVATE_COMMITS_Ca, mockedPrivateCommitments);
        _harvester.collect(HadamardProductProofGenerator.Produced.PUBLIC_COMMITMENTS_CA, mockedPublicCommitments);
        _harvester.collect(HadamardProductProofGenerator.Produced.PRIVATE_COMMITMENTS_D, mockedPrivateCommitments);
        _harvester.collect(ZeroProofGenerator.Produced.PRIVATE_COMMITMENTS_A, mockedPrivateCommitments);
        _harvester.collect(ZeroProofGenerator.Produced.PRIVATE_COMMITMENTS_cA, mockedPrivateCommitments);
        _harvester.collect(ZeroProofGenerator.Produced.EXPONENTS_MATRIX_A, exponents);
        _harvester.collect(ZeroProofGenerator.Produced.EXPONENTS_MATRIX_B, exponents);
        _harvester.collect(HadamardProductProofGenerator.Produced.CHALLENGE_INNER_PRODUCT,
            ExponentTools.getRandomExponent(q));
    }

    @Test
    public void generate_zero_proof_correctly() {

        _sut = new ParallelZeroProofGenerator(m, n, q, commitmentParams, limMultiExpo);

        _sut.generate(_harvester);

        final ZeroProofAnswer zeroProofAnswer =
            _harvester.offer(ZeroProofGenerator.Produced.ANSWER, ZeroProofAnswer.class);

        assertThat(zeroProofAnswer != null, is(true));
    }
}
