/*
 * 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.digital.envelope.factory;

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.util.Arrays;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.asymmetric.utils.AsymmetricTestDataGenerator;
import com.scytl.cryptolib.commons.constants.Constants;
import com.scytl.cryptolib.digital.envelope.configuration.DigitalEnvelopePolicy;
import com.scytl.cryptolib.digital.envelope.configuration.DigitalEnvelopePolicyFromProperties;
import com.scytl.cryptolib.primitives.primes.utils.PrimitivesTestDataGenerator;

public class DigitalEnvelopeTest {

    private static final int DATA_BYTE_LENGTH = 100;

    private static final int NUM_ASYMMETRIC_KEY_PAIRS = 5;

    private static byte[] _data;

    private static PublicKey[] _publicKeys;

    private static PrivateKey[] _privateKeys;

    private static CryptoDigitalEnvelopeGenerator _digitalEnvelopeGenerator;

    private static CryptoDigitalEnvelopeOpener _digitalEnvelopeOpener;

    @BeforeClass
    public static void setUp() throws GeneralCryptoLibException {

        Security.addProvider(new BouncyCastleProvider());

        _data = PrimitivesTestDataGenerator.getByteArray(DATA_BYTE_LENGTH);

        KeyPair[] keyPairs =
            AsymmetricTestDataGenerator
                .getKeyPairsForEncryption(NUM_ASYMMETRIC_KEY_PAIRS);
        _publicKeys =
            AsymmetricTestDataGenerator.extractPublicKeys(keyPairs);
        _privateKeys =
            AsymmetricTestDataGenerator.extractPrivateKeys(keyPairs);

        DigitalEnvelopePolicy digitalEnvelopePolicy =
            new DigitalEnvelopePolicyFromProperties(
                Constants.CRYPTOLIB_POLICY_PROPERTIES_FILE_PATH);

        _digitalEnvelopeGenerator =
            new DigitalEnvelopeFactory(digitalEnvelopePolicy)
                .createGenerator();

        _digitalEnvelopeOpener =
            new DigitalEnvelopeFactory(digitalEnvelopePolicy)
                .createOpener();
    }

    @AfterClass
    public static void tearDown() {

        Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
    }

    @Test
    public void testGenerateAndOpenDigitalEnvelope()
            throws GeneralCryptoLibException {

        CryptoDigitalEnvelope digitalEnvelope =
            _digitalEnvelopeGenerator.generate(_data, _publicKeys);

        for (int i = 0; i < _privateKeys.length; i++) {
            byte[] data =
                _digitalEnvelopeOpener.open(digitalEnvelope,
                    _privateKeys[i]);

            Assert.assertTrue(Arrays.equals(data, _data));
        }
    }
}
