/*
 * 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.products.ov.commons.signature;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import com.scytl.cryptolib.api.asymmetric.AsymmetricServiceAPI;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.asymmetric.service.AsymmetricService;

/**
 * Tests of {@link SignatureOutputStream}.
 */
public class SignatureOutputStreamTest {
    private static final byte[] DATA = {0, 1, 2 };

    private AsymmetricServiceAPI service;

    private KeyPair pair;

    private Signature signature;

    private ByteArrayOutputStream bytes;

    private SignatureOutputStream stream;

    @BeforeClass
    public static void init() {
        Security.addProvider(new BouncyCastleProvider());
    }

    @Before
    public void setUp() throws GeneralCryptoLibException {
        service = new AsymmetricService();
        pair = service.getKeyPairForSigning();
        signature = SignatureFactoryImpl.newInstance().newSignature();
        bytes = new ByteArrayOutputStream(3);
        stream = new SignatureOutputStream(bytes, signature);
    }

    @Test(expected = IOException.class)
    public void testWriteArrayIntIntSignatureException()
            throws IOException, InvalidKeyException, SignatureException, GeneralCryptoLibException {
        stream.write(DATA);
    }

    @Test
    public void testWriteByteArrayIntInt()
            throws InvalidKeyException, IOException, SignatureException, GeneralCryptoLibException {
        signature.initSign(pair.getPrivate());
        stream.write(DATA, 0, 2);
        stream.write(DATA, 2, 1);
        assertArrayEquals(DATA, bytes.toByteArray());
        assertTrue(service.verifySignature(signature.sign(), pair.getPublic(), DATA));
    }

    @Test
    public void testWriteInt() throws IOException, InvalidKeyException, SignatureException, GeneralCryptoLibException {
        signature.initSign(pair.getPrivate());
        for (byte b : DATA) {
            stream.write(b);
        }
        assertArrayEquals(DATA, bytes.toByteArray());
        assertTrue(service.verifySignature(signature.sign(), pair.getPublic(), DATA));
    }

    @Test(expected = IOException.class)
    public void testWriteIntSignatureException()
            throws IOException, InvalidKeyException, SignatureException, GeneralCryptoLibException {
        stream.write(0);
    }
}
