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

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import com.scytl.cryptolib.elgamal.bean.CiphertextImpl;
import com.scytl.cryptolib.elgamal.cryptoapi.Ciphertext;
import com.scytl.cryptolib.mathematical.groups.impl.ZpGroupElement;

public class CiphertextImplSerializationTest {

    private static BigInteger p;

    private static BigInteger q;

    private static CustomObjectMapper _target = new CustomObjectMapper();

    @BeforeClass
    public static void setUp() {

        p = new BigInteger("23");

        q = new BigInteger("11");
    }

    @Test
    public void whenSerializeAndDeserializeThenOk_1phi() throws Exception {

        BigInteger gammaValue = new BigInteger("4");
        ZpGroupElement gamma = new ZpGroupElement(gammaValue, p, q);

        BigInteger phi1Value = new BigInteger("6");
        ZpGroupElement phi1 = new ZpGroupElement(phi1Value, p, q);

        List<ZpGroupElement> phis = new ArrayList<ZpGroupElement>();
        phis.add(phi1);

        Ciphertext ciphertextImpl = new CiphertextImpl(gamma, phis);

        final Path filenameWrittenFile = Paths.get("target/ciphertext_1phi.json");
        Files.deleteIfExists(filenameWrittenFile);
        FileOutputStream output = new FileOutputStream(filenameWrittenFile.toFile());
        _target.writeValue(output, ciphertextImpl);

        FileInputStream input = new FileInputStream(filenameWrittenFile.toFile());
        Ciphertext reconstructedCiphertextImpl = _target.readValue(input, Ciphertext.class);

        assertThatCiphertextsAreEqual(ciphertextImpl, reconstructedCiphertextImpl);
    }

    @Test
    public void whenSerializeAndDeserializeThenOk_2phis() throws Exception {

        BigInteger gammaValue = new BigInteger("4");
        ZpGroupElement gamma = new ZpGroupElement(gammaValue, p, q);

        BigInteger phi1Value = new BigInteger("6");
        ZpGroupElement phi1 = new ZpGroupElement(phi1Value, p, q);

        BigInteger phi2Value = new BigInteger("8");
        ZpGroupElement phi2 = new ZpGroupElement(phi2Value, p, q);

        List<ZpGroupElement> phis = new ArrayList<ZpGroupElement>();
        phis.add(phi1);
        phis.add(phi2);

        Ciphertext ciphertextImpl = new CiphertextImpl(gamma, phis);

        final Path filenameWrittenFile = Paths.get("target/ciphertext_2phis.json");
        Files.deleteIfExists(filenameWrittenFile);
        FileOutputStream output = new FileOutputStream(filenameWrittenFile.toFile());

        _target.writeValue(output, ciphertextImpl);

        FileInputStream input = new FileInputStream(filenameWrittenFile.toFile());
        Ciphertext reconstructedCiphertextImpl = _target.readValue(input, Ciphertext.class);

        assertThatCiphertextsAreEqual(ciphertextImpl, reconstructedCiphertextImpl);
    }

    private void assertThatCiphertextsAreEqual(Ciphertext ciphertextImpl, Ciphertext reconstructedCiphertextImpl) {

        Assert.assertTrue(ciphertextImpl.getGamma().equals(reconstructedCiphertextImpl.getGamma()));
        Assert.assertEquals(ciphertextImpl.getPhis(), reconstructedCiphertextImpl.getPhis());
    }
}
