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

import java.security.KeyPair;
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.RootCertificateData;
import com.scytl.cryptolib.certificates.bean.ValidityDates;
import com.scytl.cryptolib.certificates.bean.X509CertificateType;
import com.scytl.cryptolib.certificates.bean.X509DistinguishedName;
import com.scytl.cryptolib.certificates.cryptoapi.CryptoAPIX509Certificate;
import com.scytl.cryptolib.certificates.factory.CryptoX509Certificate;

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

@RunWith(JMockit.class)
public class X509CertificateChainValidatorParametersTest {

    private X509CertificateChainValidator _target;

    @Injectable
    CryptoX509Certificate _certificate;

    @Injectable
    X509Certificate leafCertificate;

    @Injectable
    CryptoX509Certificate cryptoLeafCertificate;

    @Injectable
    X509DistinguishedName subjectLeafCertificate;

    @Injectable
    X509Certificate trustedCertificate;

    @Injectable
    X509DistinguishedName subjectChain0;

    @Injectable
    X509DistinguishedName subjectChain1;

    @Injectable
    X509Certificate certificateChain0;

    private KeyPair _rootKeys;

    private RootCertificateData _rootCertificateData;

    private CryptoAPIX509Certificate _rootAuthorityX509Certificate;

    private KeyPair _intermediateKeys;

    private CertificateData _leafCertificateData;

    private X509DistinguishedName _intermediateSubjectDn;

    private CryptoAPIX509Certificate _leafX509Certificate;

    private X509DistinguishedName _leafSubjectDn;

    private KeyPair _leafKeys;

    private CryptoAPIX509Certificate _intermediateAuthorityX509Certificate;

    private CertificateData _intermediateCertificateData;

    private ValidityDates _rootValidityDates;

    private ValidityDates _intermediateValidityDates;

    private ValidityDates _leafValidityDates;

    @Test
    public void validatorCreationOKyTest()
            throws GeneralCryptoLibException {
        X509CertificateType leafKeyType = X509CertificateType.ENCRYPT;
        X509DistinguishedName[] subjects = new X509DistinguishedName[1];
        subjects[0] = subjectChain0;
        X509Certificate[] chain = new X509Certificate[1];
        chain[0] = leafCertificate;

        _target = new X509CertificateChainValidator(leafCertificate,
            leafKeyType, subjectLeafCertificate, chain, subjects,
            trustedCertificate);

    }

    @Test(expected = GeneralCryptoLibException.class)
    public void trustedCertificateNullTest()
            throws GeneralCryptoLibException {
        X509CertificateType leafKeyType = X509CertificateType.ENCRYPT;
        X509DistinguishedName[] subjects = new X509DistinguishedName[1];
        subjects[0] = subjectChain0;
        X509Certificate[] chain = new X509Certificate[1];
        chain[0] = leafCertificate;

        _target = new X509CertificateChainValidator(leafCertificate,
            leafKeyType, subjectLeafCertificate, chain, subjects, null);

    }

    @Test(expected = GeneralCryptoLibException.class)
    public void subjectLeafCertificateNullTest()
            throws GeneralCryptoLibException {
        X509CertificateType leafKeyType = X509CertificateType.ENCRYPT;
        X509DistinguishedName[] subjects = new X509DistinguishedName[1];
        subjects[0] = subjectChain0;
        X509Certificate[] chain = new X509Certificate[1];
        chain[0] = leafCertificate;

        _target = new X509CertificateChainValidator(leafCertificate,
            leafKeyType, null, chain, subjects, trustedCertificate);

    }

    public void subjectsAndChainLengthErrorTest()
            throws GeneralCryptoLibException {
        X509CertificateType leafKeyType = X509CertificateType.ENCRYPT;
        X509DistinguishedName[] subjects = new X509DistinguishedName[2];
        subjects[0] = subjectChain0;
        subjects[1] = subjectChain1;
        X509Certificate[] chain = new X509Certificate[1];
        chain[0] = leafCertificate;

        _target = new X509CertificateChainValidator(leafCertificate,
            leafKeyType, subjectLeafCertificate, chain, subjects,
            trustedCertificate);

    }

    @Test(expected = GeneralCryptoLibException.class)
    public void leafCertificateNullTest()
            throws GeneralCryptoLibException {
        X509CertificateType leafKeyType = X509CertificateType.ENCRYPT;
        X509DistinguishedName[] subjects = new X509DistinguishedName[2];
        subjects[0] = subjectChain0;
        subjects[1] = subjectChain1;
        X509Certificate[] chain = new X509Certificate[1];
        chain[0] = leafCertificate;

        _target = new X509CertificateChainValidator(null, leafKeyType,
            subjectLeafCertificate, chain, subjects, trustedCertificate);

    }

    @Test(expected = GeneralCryptoLibException.class)
    public void chainEmptyTest() throws GeneralCryptoLibException {
        X509CertificateType leafKeyType = X509CertificateType.ENCRYPT;
        X509DistinguishedName[] subjects = new X509DistinguishedName[1];
        subjects[0] = subjectChain0;
        X509Certificate[] chain = new X509Certificate[0];

        _target = new X509CertificateChainValidator(leafCertificate,
            leafKeyType, subjectLeafCertificate, chain, subjects,
            trustedCertificate);

    }

    @Test(expected = GeneralCryptoLibException.class)
    public void chainNullTest() throws GeneralCryptoLibException {
        X509CertificateType leafKeyType = X509CertificateType.ENCRYPT;
        X509DistinguishedName[] subjects = new X509DistinguishedName[1];
        subjects[0] = subjectChain0;
        X509Certificate[] chain = null;

        _target = new X509CertificateChainValidator(leafCertificate,
            leafKeyType, subjectLeafCertificate, chain, subjects,
            trustedCertificate);

    }

    @Test
    public void chainAndSubjectsNullTest()
            throws GeneralCryptoLibException {
        X509CertificateType leafKeyType = X509CertificateType.ENCRYPT;
        X509DistinguishedName[] subjects = null;
        X509Certificate[] chain = null;

        _target = new X509CertificateChainValidator(leafCertificate,
            leafKeyType, subjectLeafCertificate, chain, subjects,
            trustedCertificate);

    }

    @Test
    public void chainAndSubjectsEmptyTest()
            throws GeneralCryptoLibException {
        X509CertificateType leafKeyType = X509CertificateType.ENCRYPT;
        X509DistinguishedName[] subjects = new X509DistinguishedName[0];
        X509Certificate[] chain = new X509Certificate[0];

        _target = new X509CertificateChainValidator(leafCertificate,
            leafKeyType, subjectLeafCertificate, chain, subjects,
            trustedCertificate);

    }

    @Test(expected = GeneralCryptoLibException.class)
    public void subjectsEmptyTest() throws GeneralCryptoLibException {
        X509CertificateType leafKeyType = X509CertificateType.ENCRYPT;
        X509DistinguishedName[] subjects = new X509DistinguishedName[0];
        X509Certificate[] chain = new X509Certificate[1];
        chain[0] = leafCertificate;

        _target = new X509CertificateChainValidator(leafCertificate,
            leafKeyType, subjectLeafCertificate, chain, subjects,
            trustedCertificate);

    }

    @Test(expected = GeneralCryptoLibException.class)
    public void subjectsNullTest() throws GeneralCryptoLibException {
        X509CertificateType leafKeyType = X509CertificateType.ENCRYPT;
        X509DistinguishedName[] subjects = null;
        X509Certificate[] chain = new X509Certificate[1];
        chain[0] = leafCertificate;

        _target = new X509CertificateChainValidator(leafCertificate,
            leafKeyType, subjectLeafCertificate, chain, subjects,
            trustedCertificate);

    }

}
