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

import static org.junit.Assert.assertEquals;

import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import com.scytl.cryptolib.api.exceptions.CryptoLibException;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.commons.constants.Constants;
import com.scytl.cryptolib.commons.utils.system.OperatingSystem;
import com.scytl.cryptolib.primitives.securerandom.configuration.ConfigSecureRandomAlgorithmAndProvider;

import mockit.Deencapsulation;

public class X509CertificateGeneratorPolicyFromPropertiesTest {

    private static OperatingSystem _os;

    private X509CertificateGeneratorPolicyFromProperties _certificateGeneratorPolicyFromProperties;

    @BeforeClass
    public static void setUp()
            throws NoSuchAlgorithmException, NoSuchProviderException {
        _os = OperatingSystem.current();

    }

    @Before
    public void setup() throws GeneralCryptoLibException {
        _certificateGeneratorPolicyFromProperties =
            new X509CertificateGeneratorPolicyFromProperties(
                Constants.CRYPTOLIB_POLICY_PROPERTIES_FILE_PATH);
    }

    @After
    public void revertSystemHelper()
            throws NoSuchAlgorithmException, NoSuchProviderException {
        Deencapsulation.setField(OperatingSystem.class, "current",
            _os);

    }

    @Test(expected = CryptoLibException.class)
    public void whenCreateX509CertificateGeneratorPolicyPassingAnIncorrectPath()
            throws GeneralCryptoLibException {
        new X509CertificateGeneratorPolicyFromProperties("somePath");
    }

    @Test(expected = CryptoLibException.class)
    public void whenCreateX509CertificateGeneratorPolicyWithInvalidLabels()
            throws GeneralCryptoLibException {
        new X509CertificateGeneratorPolicyFromProperties(
            "properties/cryptolibPolicy_invalidLabels.properties");
    }

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void whenGetAX509CertificateGeneratorPolicyFromLinux() {

        Assume.assumeTrue(OperatingSystem.LINUX.isCurrent());

        assertEquals(
            getCertificateAlgorithmAndProviderAndSecureRandomFromLinux()
                .getCertificateAlgorithmAndProvider(),
            _certificateGeneratorPolicyFromProperties
                .getCertificateAlgorithmAndProvider());

        assertEquals(
            getCertificateAlgorithmAndProviderAndSecureRandomFromLinux()
                .getSecureRandomAlgorithmAndProvider(),
            _certificateGeneratorPolicyFromProperties
                .getSecureRandomAlgorithmAndProvider());
    }

    @Test
    public void whenGetAX509CertificateGeneratorPolicyFromWindows() {

        Assume.assumeTrue(OperatingSystem.WINDOWS.isCurrent());

        assertEquals(
            getCertificateAlgorithmAndProviderAndSecureRandomFromWindows()
                .getCertificateAlgorithmAndProvider(),
            _certificateGeneratorPolicyFromProperties
                .getCertificateAlgorithmAndProvider());

        assertEquals(
            getCertificateAlgorithmAndProviderAndSecureRandomFromWindows()
                .getSecureRandomAlgorithmAndProvider(),
            _certificateGeneratorPolicyFromProperties
                .getSecureRandomAlgorithmAndProvider());
    }

    private X509CertificateGeneratorPolicy getCertificateAlgorithmAndProviderAndSecureRandomFromLinux() {
        return new X509CertificateGeneratorPolicy() {

            @Override
            public ConfigX509CertificateAlgorithmAndProvider getCertificateAlgorithmAndProvider() {
                return ConfigX509CertificateAlgorithmAndProvider.SHA256_WITH_RSA_BC;
            }

            @Override
            public ConfigSecureRandomAlgorithmAndProvider getSecureRandomAlgorithmAndProvider() {
                return ConfigSecureRandomAlgorithmAndProvider.NATIVE_PRNG_SUN;
            }

        };
    }

    private X509CertificateGeneratorPolicy getCertificateAlgorithmAndProviderAndSecureRandomFromWindows() {
        return new X509CertificateGeneratorPolicy() {

            @Override
            public ConfigX509CertificateAlgorithmAndProvider getCertificateAlgorithmAndProvider() {
                return ConfigX509CertificateAlgorithmAndProvider.SHA256_WITH_RSA_BC;
            }

            @Override
            public ConfigSecureRandomAlgorithmAndProvider getSecureRandomAlgorithmAndProvider() {
                return ConfigSecureRandomAlgorithmAndProvider.PRNG_SUN_MSCAPI;
            }

        };
    }
}
