/*
 * 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.cryptolib.proofs.maurer.proof;

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.GeneralCryptoLibException;
import com.scytl.cryptolib.mathematical.groups.impl.Exponent;
import com.scytl.cryptolib.proofs.proof.Proof;

/**
 * Tests of Proof class.
 */
public class ProofTest {

    private static BigInteger _two;

    private static BigInteger _three;

    private static BigInteger _four;

    private static BigInteger _q;

    private static Proof _proof;

    private static Exponent _hashValue;

    private static List<Exponent> _z;

    @BeforeClass
    public static void setUp() throws GeneralCryptoLibException {

        _q = new BigInteger("11");

        _two = new BigInteger("2");
        _three = new BigInteger("3");
        _four = new BigInteger("4");

        _hashValue = new Exponent(_q, _two);
        Exponent q11Value3 = new Exponent(_q, _three);
        Exponent q11Value4 = new Exponent(_q, _four);

        _z = new ArrayList<Exponent>();
        _z.add(q11Value3);
        _z.add(q11Value4);

        _proof = new Proof(_hashValue, _z);
    }

    @Test(expected = GeneralCryptoLibException.class)
    public void givenNullCWhenCreateProofThenException()
            throws GeneralCryptoLibException {

        Exponent nullHashValue = null;
        new Proof(nullHashValue, _z);
    }

    @Test(expected = GeneralCryptoLibException.class)
    public void givenNullZWhenCreateProofThenException()
            throws GeneralCryptoLibException {

        List<Exponent> nullZ = null;
        new Proof(_hashValue, nullZ);
    }

    @Test(expected = GeneralCryptoLibException.class)
    public void givenEmptyZWhenCreateProofThenException()
            throws GeneralCryptoLibException {

        List<Exponent> emptyZ = new ArrayList<Exponent>();
        new Proof(_hashValue, emptyZ);
    }

    @Test(expected = GeneralCryptoLibException.class)
    public void givenDifferentQsWhenCreateProofThenException()
            throws GeneralCryptoLibException {

        BigInteger differentQ = _q.add(BigInteger.ONE);

        Exponent exponentWithDifferentQ = new Exponent(differentQ, _two);
        new Proof(exponentWithDifferentQ, _z);
    }

    @Test
    public void givenProofWhenToJsonCanReconstructProof()
            throws GeneralCryptoLibException {

        String jsonStr = _proof.toJson();

        Proof reconstructedProof = Proof.fromJson(jsonStr);

        String errorMsg = "Returned proof does not equal expected proof";
        assertEquals(errorMsg, reconstructedProof, _proof);
    }

    @Test
    public void givenProofWhenGetValueThenExpectedValue()
            throws GeneralCryptoLibException {

        Exponent retrievedHashValue = _proof.getHashValue();
        Exponent expectedHashValue = new Exponent(_q, _two);

        String errorMsg =
            "Returned hash value does not match expected value";
        assertEquals(errorMsg, expectedHashValue, retrievedHashValue);
    }

    @Test
    public void givenProofWhenGetZThenExpectedValue()
            throws GeneralCryptoLibException {

        Exponent e3 = new Exponent(_q, _three);
        Exponent e4 = new Exponent(_q, _four);

        List<Exponent> listOfExponents = new ArrayList<Exponent>();
        listOfExponents.add(e3);
        listOfExponents.add(e4);

        List<Exponent> retrievedZ = _proof.getValuesList();

        String errorMsg = "Returned z does not match expected value";
        assertEquals(errorMsg, listOfExponents, retrievedZ);
    }
}
