/*
 * 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.products.ov.validation.services.input;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.googlecode.jcsv.writer.CSVEntryConverter;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.mathematical.groups.impl.ZpGroupElement;
import com.scytl.cryptolib.mathematical.groups.impl.ZpSubgroup;
import com.scytl.products.ov.commons.util.ConfigObjectMapper;
import com.scytl.products.ov.mixnet.commons.beans.ElGamalEncryptedBallot;
import com.scytl.products.ov.mixnet.commons.beans.VoteWithProof;
import com.scytl.products.ov.mixnet.commons.tools.VoteWithProofConverter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.Before;
import org.junit.Test;

/**
 * Tests of {@link VoteWithProofEntryParser}.
 */
public class VoteWithProofEntryParserTest {

  private static final BigInteger G = new BigInteger("2");
  private static final BigInteger P = new BigInteger("10");
  private static final BigInteger Q = new BigInteger("9");
  public static final String PROOF = "proof";

  private VoteWithProofEntryParser parser;
  private String[] csvContents;
  private ZpGroupElement element1;
  private ZpGroupElement element2;

  @Before
  public void setUp() throws GeneralCryptoLibException {
    ConfigObjectMapper objectMapper = new ConfigObjectMapper();
    parser = new VoteWithProofEntryParser(objectMapper);

    ZpSubgroup group = new ZpSubgroup(G, P, Q);

    element1 = new ZpGroupElement(BigInteger.valueOf(2), group);
    element2 = new ZpGroupElement(BigInteger.valueOf(4), group);

    List<ZpGroupElement> elements = new ArrayList<>();
    elements.add(element1);
    elements.add(element2);

    VoteWithProof vwp = new VoteWithProof(
        ElGamalEncryptedBallot.create(elements),
        IntStream.range(5, 8).mapToObj(
            number -> BigInteger.valueOf(number)
        ).collect(Collectors.toList()),
        PROOF
    );

    com.scytl.products.ov.mixnet.commons.tools.ConfigObjectMapper objectMapper2 = new com.scytl.products.ov.mixnet.commons.tools.ConfigObjectMapper();
	CSVEntryConverter<VoteWithProof> csvec = new VoteWithProofConverter(objectMapper2);
    csvContents = csvec.convertEntry(vwp);
  }

  @Test
  public void testParseEntry() {
    VoteWithProof voteWithProof = parser.parseEntry(csvContents);

    assertTrue(voteWithProof.getEncrypted().getElements().contains(element1));
    assertTrue(voteWithProof.getEncrypted().getElements().contains(element2));
    assertTrue(voteWithProof.getDecrypted().containsAll(IntStream.range(5, 8).mapToObj(
        number -> BigInteger.valueOf(number)
    ).collect(Collectors.toList())));
    assertEquals(voteWithProof.getProof(), PROOF);
  }

  @Test(expected = ArrayIndexOutOfBoundsException.class)
  public void testParseEntryEmpty() {
    parser.parseEntry();
  }
}
