/*
 * 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.config.it.verifiers;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.scytl.products.ov.constants.Constants;
import com.scytl.products.ov.encryption.params.generation.ElGamalEncryptionParameters;
import com.scytl.products.ov.utils.ConfigFileUtils;
import com.scytl.products.ov.utils.ConfigObjectMapper;
import org.junit.Assert;

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.text.ParseException;
import java.util.List;

/**
 * A class to execute all validations related with PreConfig command
 */
public class PreConfigVerifier {

    private static final String OUTPUT_FOLDER = "target/it/output";

    private static final File outputFolderFile = new File(OUTPUT_FOLDER);

    private final ConfigFileUtils _configFiletils = new ConfigFileUtils();

    private final ConfigObjectMapper _mapper = new ConfigObjectMapper();

    /**
     * @throws ParseException
     * @throws IOException
     * @throws JsonMappingException
     * @throws JsonParseException
     */
    public void preconfigValidations() throws ParseException, IOException {

        File timestampFolder = getLastTimestamp();
        Assert.assertEquals(2, timestampFolder.list().length);

        for (File file : timestampFolder.listFiles()) {
            if (file.getName()
                    .equals(Constants.ENCRYPTION_PARAMS_FILENAME)) {
                ElGamalEncryptionParameters elGamalEncryptionParameters = _mapper.fromJSONFileToJava(file,
                        ElGamalEncryptionParameters.class);

                Assert.assertTrue(elGamalEncryptionParameters.getP()
                        .compareTo(BigInteger.ZERO) > 0);
                Assert.assertTrue(elGamalEncryptionParameters.getQ()
                        .compareTo(BigInteger.ZERO) > 0);
                Assert.assertTrue(elGamalEncryptionParameters.getG()
                        .compareTo(BigInteger.ZERO) > 0);

                Assert.assertTrue((elGamalEncryptionParameters.getP()
                        .compareTo(elGamalEncryptionParameters.getG()) > 0) && (elGamalEncryptionParameters.getP()
                        .compareTo(elGamalEncryptionParameters.getQ()) > 0));

                Assert.assertTrue(elGamalEncryptionParameters.getG()
                        .modPow(elGamalEncryptionParameters.getQ(), elGamalEncryptionParameters.getP())
                        .equals(BigInteger.ONE));

            } else {
                // listPrimes.txt file case
                List<String> lines = Files.readAllLines(file.toPath());
                for (String line : lines) {
                    Assert.assertTrue(new BigInteger(line).isProbablePrime(100));
                }
                Assert.assertEquals(20, lines.size());
            }
        }

    }

    /**
     * @return
     * @throws ParseException
     */
    private File getLastTimestamp() throws ParseException {
        return _configFiletils.getLastFolderTimestamp(outputFolderFile);
    }

}
