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

import com.scytl.cryptolib.api.exceptions.CryptoLibException;
import com.scytl.cryptolib.asymmetric.cipher.configuration.ConfigAsymmetricCipherAlgorithmAndSpec;
import com.scytl.cryptolib.asymmetric.keypair.configuration.ConfigEncryptionKeyPairAlgorithmAndSpec;
import com.scytl.cryptolib.asymmetric.keypair.configuration.ConfigSigningKeyPairAlgorithmAndSpec;
import com.scytl.cryptolib.commons.configuration.PolicyFromPropertiesHelper;
import com.scytl.cryptolib.primitives.securerandom.configuration.ConfigSecureRandomAlgorithmAndProvider;
import com.scytl.cryptolib.symmetric.cipher.configuration.ConfigSymmetricCipherAlgorithmAndSpec;
import com.scytl.cryptolib.symmetric.key.configuration.ConfigHmacSecretKeyAlgorithmAndSpec;
import com.scytl.cryptolib.symmetric.key.configuration.ConfigSecretKeyAlgorithmAndSpec;
import com.scytl.cryptolib.symmetric.mac.configuration.ConfigMacAlgorithmAndProvider;

/**
 * Implementation of the interface {@link DigitalEnvelopePolicy}, which reads
 * values from a properties input.
 * <P>
 * Instances of this class are immutable.
 */
public class DigitalEnvelopePolicyFromProperties implements
        DigitalEnvelopePolicy {

    private final ConfigSecureRandomAlgorithmAndProvider _secureRandomAlgorithmAndProvider;

    private final ConfigSecretKeyAlgorithmAndSpec _secretKeyAlgorithmAndSpec;

    private final ConfigHmacSecretKeyAlgorithmAndSpec _macSecretKeyAlgorithmAndSpec;

    private final ConfigMacAlgorithmAndProvider _macAlgorithmAndProvider;

    private final ConfigSymmetricCipherAlgorithmAndSpec _symmetricCipherAlgorithmAndSpec;

    private final ConfigAsymmetricCipherAlgorithmAndSpec _asymmetricCipherAlgorithmAndSpec;

    private final ConfigSigningKeyPairAlgorithmAndSpec _signingKeyPairAlgorithmAndSpec;

    private final ConfigEncryptionKeyPairAlgorithmAndSpec _encryptionKeyPairAlgorithmAndSpec;

    /**
     * Constructs a digital envelope policy, using properties that are read from
     * a properties file with the specified path.
     *
     * @param path
     *            the path of the properties file.
     * @throws CryptoLibException
     *             if the path or the properties file is invalid.
     */
    public DigitalEnvelopePolicyFromProperties(final String path) {

        try {
            PolicyFromPropertiesHelper helper =
                new PolicyFromPropertiesHelper(path);

            _secureRandomAlgorithmAndProvider =
                ConfigSecureRandomAlgorithmAndProvider
                    .valueOf(helper
                        .getNotBlankOSDependentPropertyValue("digital.envelope.securerandom"));

            _secretKeyAlgorithmAndSpec =
                ConfigSecretKeyAlgorithmAndSpec
                    .valueOf(helper
                        .getNotBlankPropertyValue("digital.envelope.symmetric.encryptionsecretkey"));

            _macSecretKeyAlgorithmAndSpec =
                ConfigHmacSecretKeyAlgorithmAndSpec
                    .valueOf(helper
                        .getNotBlankPropertyValue("digital.envelope.symmetric.macsecretkey"));

            _macAlgorithmAndProvider =
                ConfigMacAlgorithmAndProvider
                    .valueOf(helper
                        .getNotBlankPropertyValue("digital.envelope.symmetric.mac"));

            _symmetricCipherAlgorithmAndSpec =
                ConfigSymmetricCipherAlgorithmAndSpec
                    .valueOf(helper
                        .getNotBlankPropertyValue("digital.envelope.symmetric.cipher"));

            _asymmetricCipherAlgorithmAndSpec =
                ConfigAsymmetricCipherAlgorithmAndSpec
                    .valueOf(helper
                        .getNotBlankPropertyValue("digital.envelope.asymmetric.cipher"));

            _signingKeyPairAlgorithmAndSpec =
                ConfigSigningKeyPairAlgorithmAndSpec
                    .valueOf(helper
                        .getNotBlankPropertyValue("digital.envelope.asymmetric.signingkeypair"));

            _encryptionKeyPairAlgorithmAndSpec =
                ConfigEncryptionKeyPairAlgorithmAndSpec
                    .valueOf(helper
                        .getNotBlankPropertyValue("digital.envelope.asymmetric.encryptionkeypair"));
        } catch (IllegalArgumentException e) {
            throw new CryptoLibException("Illegal property value", e);
        }
    }

    @Override
    public ConfigSecureRandomAlgorithmAndProvider getSecureRandomAlgorithmAndProvider() {

        return _secureRandomAlgorithmAndProvider;
    }

    @Override
    public ConfigSecretKeyAlgorithmAndSpec getSecretKeyAlgorithmAndSpec() {

        return _secretKeyAlgorithmAndSpec;
    }

    @Override
    public ConfigHmacSecretKeyAlgorithmAndSpec getHmacSecretKeyAlgorithmAndSpec() {

        return _macSecretKeyAlgorithmAndSpec;
    }

    @Override
    public ConfigMacAlgorithmAndProvider getMacAlgorithmAndProvider() {

        return _macAlgorithmAndProvider;
    }

    @Override
    public ConfigSymmetricCipherAlgorithmAndSpec getSymmetricCipherAlgorithmAndSpec() {

        return _symmetricCipherAlgorithmAndSpec;
    }

    @Override
    public ConfigAsymmetricCipherAlgorithmAndSpec getAsymmetricCipherAlgorithmAndSpec() {

        return _asymmetricCipherAlgorithmAndSpec;
    }

    @Override
    public ConfigSigningKeyPairAlgorithmAndSpec getSigningKeyPairAlgorithmAndSpec() {

        return _signingKeyPairAlgorithmAndSpec;
    }

    @Override
    public ConfigEncryptionKeyPairAlgorithmAndSpec getEncryptingKeyPairAlgorithmAndSpec() {

        return _encryptionKeyPairAlgorithmAndSpec;
    }
}
