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

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import com.scytl.cryptolib.api.exceptions.CryptoLibException;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.elgamal.cryptoapi.Ciphertext;
import com.scytl.cryptolib.mathematical.groups.impl.ZpSubgroup;
import com.scytl.ov.mixing.commons.ballots.ElGamalEncryptedBallots;
import com.scytl.ov.mixing.commons.configuration.ApplicationConfig;
import com.scytl.ov.mixing.commons.configuration.MixerConfig;
import com.scytl.ov.mixing.commons.configuration.locations.LocationsProvider;
import com.scytl.ov.mixing.commons.io.ElGamalEncryptedBallotsLoader;
import com.scytl.ov.mixing.commons.tests.CommonTestingUtilities;
import com.scytl.ov.mixing.commons.validation.EncryptedBallotsDuplicationValidator;
import com.scytl.ov.mixing.commons.validation.EncryptedBallotsValidator;
import com.scytl.ov.mixing.commons.validation.EncryptedBallotsValidatorManager;

public class AdaptorToolsTest {

    private static ElGamalEncryptedBallotsLoader elgamalEncryptedBallotsLoader;

    private static LocationsProvider locations;

    private static ZpSubgroup zpGroup;

    @BeforeClass
    public static void setUp() throws IOException {

        try {

            ApplicationConfig mixnetConfig = new ApplicationConfig();
            final MixerConfig mixerConfig = new MixerConfig();

            mixerConfig.setEncryptionParametersInput(new FileInputStream(
                Paths.get("src/test/resources/input/parameters/encParams_n512_p256_q32.json").toFile()));
            InputStream encryptedBallotsInput =
                new FileInputStream(Paths.get("src/test/resources/input/encryptedBallots_n512_p256_q32.csv").toFile());

            mixerConfig.setEncryptedBallotsInput(encryptedBallotsInput);
            mixnetConfig.setMixer(mixerConfig);
            locations = LocationsProvider.build(mixnetConfig);

            zpGroup = ZpSubgroup
                .fromJson(IOUtils.toString(locations.getMixerLocationsProvider().getEncryptionParametersInput()));

            final List<EncryptedBallotsValidator> listValidators = new ArrayList<>();
            listValidators.add(new EncryptedBallotsDuplicationValidator());

            EncryptedBallotsValidatorManager validator = new EncryptedBallotsValidatorManager(listValidators);
            elgamalEncryptedBallotsLoader = new ElGamalEncryptedBallotsLoader(validator);

        } catch (GeneralCryptoLibException e) {
            throw new CryptoLibException(e);
        }

    }

    @Test
    public void adaptCiphertextsTest() throws IOException {

        final ElGamalEncryptedBallots encryptedBallots = elgamalEncryptedBallotsLoader.loadCSV(zpGroup,
            locations.getMixerLocationsProvider().getEncryptedBallotsInput());

        int i = 200;
        int m = 2;
        int n = 100;

        ElGamalEncryptedBallots filteredEncryptedBallots = CommonTestingUtilities.filterBallots(encryptedBallots, i);

        List<Ciphertext> listCiphertexts = filteredEncryptedBallots.getBallots();

        Ciphertext[][] result = MatrixArranger.arrangeInCiphertextMatrix(listCiphertexts, m, n);

        Assert.assertEquals(100, result[0].length);
        Assert.assertEquals(100, result[1].length);
    }

}
