/*
 * 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.asymmetric.keypair.openssl;

import static java.text.MessageFormat.format;

import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * Integration tests.
 */
public class PerformanceTests {
    private PerformanceTests() {
    }

    /**
     * Main method.
     * <p>
     * Two arguments are supported:
     * <ul>
     * <li>The length of the RSA key, for example {@code 2048}.</li>
     * <li>The number of tests, for example {@code 100}.</li>
     * </ul>
     *
     * @param args
     */
    public static void main(final String[] args) {
        int keysize = Integer.parseInt(args[0]);
        int count = Integer.parseInt(args[1]);
        AlgorithmParameterSpec spec =
            new RSAKeyGenParameterSpec(keysize, RSAKeyGenParameterSpec.F4);
        try {
            testOpenSSLKeyPairGenerator(spec, count);
            testSunKeyPairGenerator(spec, count);
            testBCKeyPairGenerator(spec, count);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static long genKeyPairs(final KeyPairGenerator generator,
            final AlgorithmParameterSpec spec, final int count)
            throws InvalidAlgorithmParameterException {
        generator.initialize(spec);
        long start = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            generator.genKeyPair();
        }
        return System.currentTimeMillis() - start;
    }

    private static void testBCKeyPairGenerator(
            final AlgorithmParameterSpec spec, final int count)
            throws NoSuchAlgorithmException, NoSuchProviderException,
            InvalidAlgorithmParameterException {
        Security.addProvider(new BouncyCastleProvider());
        KeyPairGenerator generator =
            KeyPairGenerator.getInstance("RSA", "BC");
        long time = genKeyPairs(generator, spec, count);
        System.err
            .println(format("{0} key pairs with BC: {1}", count, time));
    }

    private static void testOpenSSLKeyPairGenerator(
            final AlgorithmParameterSpec spec, final int count)
            throws NoSuchAlgorithmException,
            InvalidAlgorithmParameterException {
        KeyPairGenerator generator =
            OpenSSLKeyPairGenerator.getInstance("RSA");
        long time = genKeyPairs(generator, spec, count);
        System.err.println(
            format("{0} key pairs with OpenSSL: {1}", count, time));
    }

    private static void testSunKeyPairGenerator(
            final AlgorithmParameterSpec spec, final int count)
            throws NoSuchAlgorithmException, NoSuchProviderException,
            InvalidAlgorithmParameterException {
        KeyPairGenerator generator =
            KeyPairGenerator.getInstance("RSA", "SunRsaSign");
        long time = genKeyPairs(generator, spec, count);
        System.err
            .println(format("{0} key pairs with Sun: {1}", count, time));
    }
}
