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

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

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import com.scytl.cryptolib.mathematical.groups.impl.Exponent;
import com.scytl.ov.mixing.commons.proofs.bg.commitments.PrivateCommitment;
import com.scytl.ov.mixing.commons.proofs.bg.commitments.PublicCommitment;
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.state.MapBasedHarvester;
import com.scytl.ov.mixing.proofs.bg.state.StateHarvester;

import mockit.Expectations;
import mockit.Mocked;
import mockit.integration.junit4.JMockit;

@RunWith(JMockit.class)
public class SecondCommitmentGeneratorTest extends BasicProofsInitializer {

    private final StateHarvester _harvester = new MapBasedHarvester();

    private com.scytl.ov.mixing.shuffle.Permutation _permutation;

    private SecondCommitmentGenerator _sut;

    @Before
    public void setUpMethod() {
        _harvester.collect(ShuffleProofGenerator.Produced.RANDOM_ORACLE, new RandomOracleHash(q));

        _permutation = getMockedPermutation();

        final FirstCommitmentGenerator firstCommitmentGenerator = new FirstCommitmentGenerator(config, _permutation,
            commitmentParams, privateAndPublicCommitmentsGenerator, limMultiExpo);

        final Exponent[][] firstCommitmentExponents = firstCommitmentGenerator.initExponents(_harvester);

        _harvester.collect(BaseCommitmentGenerator.Produced.EXPONENTS, firstCommitmentExponents);

        _sut =
            new SecondCommitmentGenerator(config, commitmentParams, privateAndPublicCommitmentsGenerator, limMultiExpo);
    }

    @Test
    public void initialize_exponents_correctly() {

        new Expectations() {
            {
                MatrixArranger.transformPermutationToExponentMatrix(_permutation, q, m, n);
            }
        };

        final Exponent[][] exponents = _sut.initExponents(_harvester);

        assertThat(exponents.length, is(m));
        assertThat(exponents[0].length, is(n));

    }

    @Test
    public void publish_commitments_correctly(@Mocked final PublicCommitment[] publicCommitments,
            @Mocked final PrivateCommitment[] privateCommitments, @Mocked final MapBasedHarvester mockedHarvester) {

        new Expectations() {
            {
                mockedHarvester.collect(SecondCommitmentGenerator.Produced.PUBLIC_COMMITS, publicCommitments);
                mockedHarvester.collect(SecondCommitmentGenerator.Produced.PRIVATE_COMMITS, privateCommitments);
            }
        };

        _sut.publishCommitments(privateCommitments, publicCommitments, mockedHarvester);

    }
}
