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

import static org.junit.Assert.assertEquals;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

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.exceptions.InvalidInputException;
import com.scytl.ov.mixing.commons.tools.GroupTools;
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 ElGamalEncryptedBallotsLoaderTest {

    private static ElGamalEncryptedBallotsLoader elGamalEncryptedBallotsLoader;

    private static LocationsProvider locProvider;

    private static ZpSubgroup zpGroup;

    @BeforeClass
    public static void setUp() throws FileNotFoundException {

        final BigInteger p = new BigInteger("15294034768093677312256663166625633354362303");
        final BigInteger q = new BigInteger("7647017384046838656128331583312816677181151");
        zpGroup = GroupTools.createGroupWithRandomGenerator(p, q);

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

        elGamalEncryptedBallotsLoader = new ElGamalEncryptedBallotsLoader(validator);

        final ApplicationConfig mixnetConfig = new ApplicationConfig();
        final MixerConfig mixerConfig = new MixerConfig();
        final Map<String, String> mapInput = new HashMap<>();
        mapInput.put("encryptedBallots", "src/test/resources/input/test");
        mixerConfig
            .setEncryptedBallotsInput(new FileInputStream(Paths.get("src/test/resources/input/test.csv").toFile()));
        mixnetConfig.setMixer(mixerConfig);
        locProvider = LocationsProvider.build(mixnetConfig);

    }

    @Test
    public void givenGoodCsvWhenLoadThenOk() throws IOException, URISyntaxException {

        final ElGamalEncryptedBallots elGamalEncryptedBallots = elGamalEncryptedBallotsLoader.loadCSV(zpGroup,
            locProvider.getMixerLocationsProvider().getEncryptedBallotsInput());

        final int numExpectedBallots = 10;
        final int numLoadedBallots = elGamalEncryptedBallots.getBallots().size();
        final String errorMsg = "Did not read the number of expected ballots. Expected: " + numExpectedBallots
            + ", but read: " + numLoadedBallots;
        assertEquals(errorMsg, numExpectedBallots, elGamalEncryptedBallots.getBallots().size());
    }

    @Ignore("Mixing will now accept encrypted ballots that are identical")
    @Test(expected = InvalidInputException.class)
    public void givenCsvWithRepeatedRowsThenException() throws IOException, URISyntaxException {

        elGamalEncryptedBallotsLoader.loadCSV(zpGroup,
            new FileInputStream(Paths.get("src/test/resources/input/", "test_contains_repeated_rows.csv").toFile()));
    }
}
