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

import java.security.Security;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.interoperation.js.commands.CommandException;
import com.scytl.cryptolib.interoperation.js.commands.CommandRunner;
import com.scytl.cryptolib.interoperation.js.commands.asymmetric.TestAsymmetricCipher;
import com.scytl.cryptolib.interoperation.js.commands.asymmetric.TestAsymmetricSigner;
import com.scytl.cryptolib.interoperation.js.commands.certificates.TestCertificate;
import com.scytl.cryptolib.interoperation.js.commands.certificates.TestCertificateChain;
import com.scytl.cryptolib.interoperation.js.commands.digital.envelope.TestDigitalEnvelope;
import com.scytl.cryptolib.interoperation.js.commands.elgamal.TestElGamalCipher;
import com.scytl.cryptolib.interoperation.js.commands.elgamal.TestElGamalCipherShortExponent;
import com.scytl.cryptolib.interoperation.js.commands.primitives.TestHash;
import com.scytl.cryptolib.interoperation.js.commands.primitives.TestPbkdfKeyDeriver;
import com.scytl.cryptolib.interoperation.js.commands.proofs.TestExponentiationProof;
import com.scytl.cryptolib.interoperation.js.commands.proofs.TestORProof;
import com.scytl.cryptolib.interoperation.js.commands.proofs.TestPlaintextEqualityProof;
import com.scytl.cryptolib.interoperation.js.commands.proofs.TestPlaintextExponentEqualityProof;
import com.scytl.cryptolib.interoperation.js.commands.proofs.TestPlaintextProof;
import com.scytl.cryptolib.interoperation.js.commands.proofs.TestSchnorrProof;
import com.scytl.cryptolib.interoperation.js.commands.proofs.TestSimplePlaintextEqualityProof;
import com.scytl.cryptolib.interoperation.js.commands.stores.TestPkcs12;
import com.scytl.cryptolib.interoperation.js.commands.stores.TestScytlKeyStore;
import com.scytl.cryptolib.interoperation.js.commands.symmetric.TestMac;
import com.scytl.cryptolib.interoperation.js.commands.symmetric.TestSymmetricCipher;

/**
 * Runs the Java-JavaScript interoperation tests for the chosen set of
 * cryptographic applications and outputs logging information about the status
 * and results of the tests. Note that the tests are run in the order in which
 * they are added to the command runner.
 */
public final class JavaJsInteroperationTester {

    private JavaJsInteroperationTester() {
    }

    /**
     * Runs the interoperation tests.
     * 
     * @param args
     *            optional command line arguments.
     * @throws GeneralCryptoLibException
     *             if any of the interoperation tests fails.
     */
    public static void main(final String[] args) throws CommandException {

        setUp();

        CommandRunner runner = new CommandRunner();

        runner.addCommand(new TestHash());
        runner.addCommand(new TestPbkdfKeyDeriver());
        runner.addCommand(new TestMac());
        runner.addCommand(new TestSymmetricCipher());
        runner.addCommand(new TestAsymmetricCipher());
        runner.addCommand(new TestAsymmetricSigner());
        runner.addCommand(new TestCertificate());
        runner.addCommand(new TestCertificateChain());
        runner.addCommand(new TestPkcs12());
        runner.addCommand(new TestScytlKeyStore());
        runner.addCommand(new TestElGamalCipher());
        runner.addCommand(new TestElGamalCipherShortExponent());
        runner.addCommand(new TestSchnorrProof());
        runner.addCommand(new TestExponentiationProof());
        runner.addCommand(new TestPlaintextProof());
        runner.addCommand(new TestSimplePlaintextEqualityProof());
        runner.addCommand(new TestPlaintextEqualityProof());
        runner.addCommand(new TestPlaintextExponentEqualityProof());
        runner.addCommand(new TestORProof());
        runner.addCommand(new TestDigitalEnvelope());

        runner.runCommands();

        tearDown();
    }

    private static void setUp() {

        Security.addProvider(new BouncyCastleProvider());
    }

    private static void tearDown() {

        Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
    }
}
