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

import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;

import org.junit.Test;
import org.junit.runner.RunWith;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.certificates.bean.CertificateData;
import com.scytl.cryptolib.certificates.bean.CertificatePublicData;
import com.scytl.cryptolib.certificates.bean.ValidityDates;
import com.scytl.cryptolib.certificates.bean.X509DistinguishedName;
import com.scytl.cryptolib.certificates.bean.extensions.AbstractCertificateExtension;
import com.scytl.cryptolib.certificates.factory.CryptoX509CertificateGenerator;
import com.scytl.cryptolib.commons.configuration.Provider;
import com.scytl.cryptolib.primitives.securerandom.factory.CryptoRandomInteger;

import mockit.Deencapsulation;
import mockit.Expectations;
import mockit.Injectable;
import mockit.integration.junit4.JMockit;

@RunWith(JMockit.class)
public class CryptoX509CertificateGeneratorNegativeTest {

    private static final String SIGNATURE_ALGORITHM = "signatureAlgorithm";

    private CryptoX509CertificateGenerator _target;

    @Injectable
    private Provider provider;

    @Injectable
    private CryptoRandomInteger cryptoRandomInteger;

    @Injectable
    private PrivateKey issuerPrivateKey;

    @Injectable
    private PublicKey publicKey;

    @Injectable
    private X509DistinguishedName subjectDn;

    @Injectable
    private X509DistinguishedName issuerDn;

    @Injectable
    private ValidityDates validityDates;

    @Injectable
    private X509Certificate x509Certificate;

    @Injectable
    private AbstractCertificateExtension abstractCertificateExtension;

    @Test(expected = GeneralCryptoLibException.class)
    public void generateNullExtensionTest()
            throws GeneralCryptoLibException {

        AbstractCertificateExtension[] extensions =
            new AbstractCertificateExtension[] {null };
        final CertificatePublicData certificateGenerationParameters =
            new CertificateData() {
                {
                    setIssuerDn(issuerDn);
                    setSubjectDn(subjectDn);
                    setSubjectPublicKey(publicKey);
                    setValidityDates(validityDates);
                }
            };

        new Expectations() {
            {
                _target = Deencapsulation.newInstance(
                    CryptoX509CertificateGenerator.class,
                    SIGNATURE_ALGORITHM, provider, cryptoRandomInteger);

            }
        };
        _target.generate(certificateGenerationParameters, extensions,
            issuerPrivateKey);
    }

    @Test(expected = GeneralCryptoLibException.class)
    public void generateNullIssuerPrivateKeyTest()
            throws GeneralCryptoLibException {

        AbstractCertificateExtension[] extensions =
            new AbstractCertificateExtension[] {
                    abstractCertificateExtension };
        final CertificatePublicData certificateGenerationParameters =
            new CertificateData() {
                {
                    setIssuerDn(issuerDn);
                    setSubjectDn(subjectDn);
                    setSubjectPublicKey(publicKey);
                    setValidityDates(validityDates);
                }
            };

        new Expectations() {
            {
                _target = Deencapsulation.newInstance(
                    CryptoX509CertificateGenerator.class,
                    SIGNATURE_ALGORITHM, provider, cryptoRandomInteger);

            }
        };
        _target.generate(certificateGenerationParameters, extensions,
            null);
    }

    @Test(expected = GeneralCryptoLibException.class)
    public void generateNullSubjectDnTest()
            throws GeneralCryptoLibException {

        AbstractCertificateExtension[] extensions =
            new AbstractCertificateExtension[] {
                    abstractCertificateExtension };
        final CertificatePublicData certificateGenerationParameters =
            new CertificateData() {
                {
                    setIssuerDn(issuerDn);
                    setSubjectDn(null);
                    setSubjectPublicKey(publicKey);
                    setValidityDates(validityDates);
                }
            };

        new Expectations() {
            {
                _target = Deencapsulation.newInstance(
                    CryptoX509CertificateGenerator.class,
                    SIGNATURE_ALGORITHM, provider, cryptoRandomInteger);

            }
        };
        _target.generate(certificateGenerationParameters, extensions,
            issuerPrivateKey);
    }

    @Test(expected = GeneralCryptoLibException.class)
    public void generateNullIssuerDnTest()
            throws GeneralCryptoLibException {

        AbstractCertificateExtension[] extensions =
            new AbstractCertificateExtension[] {
                    abstractCertificateExtension };
        final CertificatePublicData certificateGenerationParameters =
            new CertificateData() {
                {
                    setIssuerDn(null);
                    setSubjectDn(subjectDn);
                    setSubjectPublicKey(publicKey);
                    setValidityDates(validityDates);
                }
            };

        new Expectations() {
            {
                _target = Deencapsulation.newInstance(
                    CryptoX509CertificateGenerator.class,
                    SIGNATURE_ALGORITHM, provider, cryptoRandomInteger);

            }
        };
        _target.generate(certificateGenerationParameters, extensions,
            issuerPrivateKey);
    }

    @Test(expected = GeneralCryptoLibException.class)
    public void generateNullValidityDatesTest()
            throws GeneralCryptoLibException {

        AbstractCertificateExtension[] extensions =
            new AbstractCertificateExtension[] {
                    abstractCertificateExtension };
        final CertificatePublicData certificateGenerationParameters =
            new CertificateData() {
                {
                    setIssuerDn(issuerDn);
                    setSubjectDn(subjectDn);
                    setSubjectPublicKey(publicKey);
                    setValidityDates(null);
                }
            };

        new Expectations() {
            {
                _target = Deencapsulation.newInstance(
                    CryptoX509CertificateGenerator.class,
                    SIGNATURE_ALGORITHM, provider, cryptoRandomInteger);

            }
        };
        _target.generate(certificateGenerationParameters, extensions,
            issuerPrivateKey);
    }
}
