package com.scytl.math;

import static com.scytl.math.BigIntegers.modMultiply;
import static com.scytl.math.BigIntegers.modPow;
import static com.scytl.math.BigIntegers.multiply;
import static java.util.Arrays.asList;

import java.math.BigInteger;
import java.util.List;

/**
 * Application which runs integration tests.
 * <p>
 * Some parts the library depend on native code, so it is very difficult to test
 * them during the standard Maven build. Developers can use this application to
 * test those parts locally.
 * 
 * @author aakimov
 */
public class IntegrationTests {

    private IntegrationTests() {
    }

    /**
     * Main method.
     * 
     * @param args
     */
    public static void main(String[] args) {
        testMultiply();
        testModMultiply();
        testModPow();
        testMultiExponentiation();
    }

    private static void testModMultiply() {
        BigInteger number1 = BigInteger.valueOf(3);
        BigInteger number2 = BigInteger.valueOf(5);
        BigInteger modulus = BigInteger.valueOf(7);
        System.out.println(
                "ModMultiply: " + modMultiply(number1, number2, modulus));
    }

    private static void testModPow() {
        BigInteger base = BigInteger.valueOf(3);
        BigInteger exponent = BigInteger.valueOf(10);
        BigInteger modulus = BigInteger.valueOf(5);
        System.out.println("ModPow: " + modPow(base, exponent, modulus));
    }

    private static void testMultiExponentiation() {
        List<BigInteger> bases = asList(BigInteger.valueOf(2),
                BigInteger.valueOf(3));
        List<BigInteger> exponents = asList(BigInteger.valueOf(5),
                BigInteger.valueOf(7));
        BigInteger modulus = BigInteger.valueOf(11);
        MultiExponentiatorFactory factory = MultiExponentiatorFactoryImpl
                .getInstance();
        MultiExponentiator exponentiator = factory.newMultiExponentiator(bases,
                modulus, 3);
        System.out.println("MultiExponentiation: "
                + exponentiator.exponentiate(exponents));
    }

    private static void testMultiply() {
        BigInteger factor1 = BigInteger.valueOf(3);
        BigInteger factor2 = BigInteger.valueOf(5);
        System.out.println("Multiply: " + multiply(factor1, factor2));

        factor1 = factor1.negate();
        System.out.println("Multiply: " + multiply(factor1, factor2));

        factor2 = factor2.negate();
        System.out.println("Multiply: " + multiply(factor1, factor2));
    }
}
