/*
 * 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.ov.mixing.proofs.bg.multiexp.basic;

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

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

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.mathematical.groups.impl.Exponent;
import com.scytl.ov.mixing.commons.beans.proofs.MultiExponentiationBasicProofAnswer;
import com.scytl.ov.mixing.commons.homomorphic.Randomness;
import com.scytl.ov.mixing.commons.homomorphic.impl.GjosteenElGamalRandomness;
import com.scytl.ov.mixing.commons.proofs.bg.commitments.PrivateCommitment;
import com.scytl.ov.mixing.commons.tools.ExponentTools;
import com.scytl.ov.mixing.commons.tools.MatrixArranger;
import com.scytl.ov.mixing.commons.tools.RandomOracleHash;
import com.scytl.ov.mixing.proofs.bg.BasicProofsInitializer;
import com.scytl.ov.mixing.proofs.bg.shuffle.SecondCommitmentGenerator;
import com.scytl.ov.mixing.proofs.bg.state.CommonStateLabels;
import com.scytl.ov.mixing.proofs.bg.state.MapBasedHarvester;
import com.scytl.ov.mixing.proofs.bg.state.StateHarvester;

public class ParallelBasicAnswerGeneratorTest extends BasicProofsInitializer {

    private final StateHarvester _harvester = new MapBasedHarvester();

    private ParallelBasicAnswerGenerator _sut;

    @Before
    public void initHarvester() throws GeneralCryptoLibException {

        _harvester.collect(BasicProofGenerator.Produced.MULTIEXP_BASIC_RO, new RandomOracleHash(q));

        _harvester.collect(CommonStateLabels.CIPHERTEXTS, getMockedReEncryptedCiphertexts());

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

        _harvester.collect(BasicInitialMessageGenerator.Produced.EXPONENTS_A0, exponents[0]);
        _harvester.collect(BasicInitialMessageGenerator.Produced.EXPONENTS_ARR, exponents);

        final PrivateCommitment[] privateCommitmentsB = getMockedPrivateCommitments(exponents);
        _harvester.collect(SecondCommitmentGenerator.Produced.PRIVATE_COMMITS, privateCommitmentsB);

        _harvester.collect(BasicInitialMessageGenerator.Produced.EXPONENTS_R0, ExponentTools.getRandomExponent(q));

        _harvester.collect(BasicInitialMessageGenerator.Produced.EXPONENTS_MULTIARR_B, exponents[0]);

        _harvester.collect(BasicInitialMessageGenerator.Produced.EXPONENTS_ARR_S, exponents[0]);

        final Randomness[] tauArray = new GjosteenElGamalRandomness[exponents[0].length];

        for (int i = 0; i < exponents[0].length; i++) {
            tauArray[i] = new GjosteenElGamalRandomness(exponents[0][i]);
        }

        _harvester.collect(BasicInitialMessageGenerator.Produced.RANDOMNESS_TAU_ARR, tauArray);

    }

    @Test
    public void generate_the_basic_answer_message_correctly() {

        _sut = new ParallelBasicAnswerGenerator();
        _sut.generate(_harvester);

        final MultiExponentiationBasicProofAnswer multiExponentiationBasicProofAnswer = _harvester
            .offer(BasicAnswerGenerator.Produced.BASIC_MULTIEXP_ANSWER, MultiExponentiationBasicProofAnswer.class);

        assertThat(multiExponentiationBasicProofAnswer != null, is(true));

    }
}
