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

import static org.junit.Assert.assertEquals;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

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.bean.CiphertextImpl;
import com.scytl.cryptolib.elgamal.cryptoapi.Ciphertext;
import com.scytl.cryptolib.mathematical.groups.impl.ZpGroupElement;

public class ElGamalEncryptedBallotsTest {

    private static CiphertextImpl _ballotA;

    private static CiphertextImpl _ballotB;

    private static CiphertextImpl _ballotC;

    private static BigInteger _p;

    private static BigInteger _q;

    private static ElGamalEncryptedBallots _target;

    @BeforeClass
    public static void setUp() {

        _p = new BigInteger("15294034768093677312256663166625633354362303");
        _q = new BigInteger("7647017384046838656128331583312816677181151");

        _target = new ElGamalEncryptedBallots(createListOfBallots());
    }

    private static List<Ciphertext> createListOfBallots() {

        try {
            final List<ZpGroupElement> elementsA = new ArrayList<>();
            elementsA.add(new ZpGroupElement(new BigInteger("7606155287466709247547562508296526348227245"), _p, _q));
            elementsA.add(new ZpGroupElement(new BigInteger("9894101363857510707841445959199640374054748"), _p, _q));
            _ballotA = new CiphertextImpl(elementsA.get(0), elementsA.subList(1, elementsA.size()));

            final List<ZpGroupElement> elementsB = new ArrayList<>();
            elementsB.add(new ZpGroupElement(new BigInteger("4012556967239296284125919604329103854893595"), _p, _q));
            elementsB.add(new ZpGroupElement(new BigInteger("6054959594806155309765068576952771674747761"), _p, _q));
            _ballotB = new CiphertextImpl(elementsB.get(0), elementsB.subList(1, elementsB.size()));

            final List<ZpGroupElement> elementsC = new ArrayList<>();
            elementsC.add(new ZpGroupElement(new BigInteger("11583975953794885768215634543368899452667420"), _p, _q));
            elementsC.add(new ZpGroupElement(new BigInteger("2114609311581369961287633946894396492461861"), _p, _q));
            _ballotC = new CiphertextImpl(elementsC.get(0), elementsC.subList(1, elementsC.size()));

            List<Ciphertext> listOfBallots = new ArrayList<>();
            listOfBallots.add(_ballotA);
            listOfBallots.add(_ballotB);
            listOfBallots.add(_ballotC);

            return listOfBallots;

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

    @Test
    public void whenRetrieveBallotsThenExpected() throws GeneralCryptoLibException {

        List<Ciphertext> listOfBallots = createListOfBallots();

        List<Ciphertext> retrievedListOfBallots = _target.getBallots();

        assertEquals(serializeBallots(retrievedListOfBallots), serializeBallots(listOfBallots));
    }

    private String serializeBallots(List<Ciphertext> listOfBallots) throws GeneralCryptoLibException {
        StringBuffer sb = new StringBuffer();
        for (Ciphertext ciphertextImpl : listOfBallots) {
            sb.append(ciphertextImpl.getGamma().toJson());
            List<ZpGroupElement> phis = ciphertextImpl.getPhis();
            for (ZpGroupElement zpGroupElement : phis) {
                sb.append(zpGroupElement.toJson());
            }
        }
        return sb.toString();
    }
}
