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

import static org.junit.Assert.assertTrue;

import org.junit.Before;
import org.junit.Test;

import com.scytl.cryptolib.api.exceptions.CryptoLibException;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.commons.utils.system.OperatingSystem;
import com.scytl.cryptolib.elgamal.bean.ElGamalEncryptionParameters;
import com.scytl.cryptolib.elgamal.configuration.ConfigGroupType;
import com.scytl.cryptolib.elgamal.configuration.ElGamalPolicy;
import com.scytl.cryptolib.primitives.securerandom.configuration.ConfigSecureRandomAlgorithmAndProvider;
import com.scytl.cryptolib.primitives.securerandom.factory.CryptoRandomInteger;
import com.scytl.cryptolib.primitives.securerandom.factory.SecureRandomFactory;

public class ElGamalEncryptionParamsGeneratorIT {

    private QuadResParamsGenerator _quadResParamsGenerator;

    private static final int CERTAINTY_LEVEL = 80;

    private ConfigGroupType _subgroup;

    @Before
    public void beforeTest() {

        ElGamalPolicy policy = getPolicy();
        CryptoRandomInteger cryptoRandomInteger =
            new SecureRandomFactory(policy).createIntegerRandom();

        _subgroup = policy.getGroupType();

        _quadResParamsGenerator =
            new QuadResParamsGenerator(_subgroup.getL(), CERTAINTY_LEVEL,
                cryptoRandomInteger);
    }

    @Test
    public void testGenerate() throws GeneralCryptoLibException {

        ElGamalEncryptionParameters params =
            _quadResParamsGenerator.generate();

        assertTrue(params.getP().isProbablePrime(CERTAINTY_LEVEL));
        assertTrue(params.getQ().isProbablePrime(CERTAINTY_LEVEL));

        int constructedPLength = params.getP().bitLength();
        assertTrue(constructedPLength <= _subgroup.getL());
    }

    private static ElGamalPolicy getPolicy() {

        return new ElGamalPolicy() {

            @Override
            public ConfigGroupType getGroupType() {
                return ConfigGroupType.QR_2048;
            }

            @Override
            public ConfigSecureRandomAlgorithmAndProvider getSecureRandomAlgorithmAndProvider() {

                switch (OperatingSystem.current()) {

                case WINDOWS:
                    return ConfigSecureRandomAlgorithmAndProvider.PRNG_SUN_MSCAPI;
                case LINUX:
                    return ConfigSecureRandomAlgorithmAndProvider.NATIVE_PRNG_SUN;
                default:
                    throw new CryptoLibException("OS not supported");
                }
            }
        };
    }

}
