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

import com.scytl.cryptolib.api.exceptions.CryptoLibException;
import com.scytl.cryptolib.commons.configuration.PolicyFromPropertiesHelper;
import com.scytl.cryptolib.primitives.derivation.configuration.ConfigKDFDerivationParameters;
import com.scytl.cryptolib.primitives.derivation.configuration.ConfigPBKDFDerivationParameters;
import com.scytl.cryptolib.primitives.securerandom.configuration.ConfigSecureRandomAlgorithmAndProvider;
import com.scytl.cryptolib.symmetric.cipher.configuration.ConfigSymmetricCipherAlgorithmAndSpec;
import com.scytl.cryptolib.symmetric.key.configuration.ConfigSecretKeyAlgorithmAndSpec;
import com.scytl.cryptolib.symmetric.key.configuration.SecretKeyPolicy;

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

    private final ConfigScytlKeyStoreTypeAndProvider _storeTypeAndProvider;

    private final ConfigKDFDerivationParameters _kdfDerivationParameters;

    private final ConfigPBKDFDerivationParameters _pbkdfDerivationParameters;

    private final ConfigSecureRandomAlgorithmAndProvider _secureRandomAlgorithmAndProvider;

    private final ConfigSecretKeyAlgorithmAndSpec _secretKeyAlgorithmAndSpec;

    private final ConfigSymmetricCipherAlgorithmAndSpec _symmetricCipherAlgorithmAndSpec;

    /**
     * Creates an instance of the class and initializes it by parameter from
     * provided path.
     *
     * @param path
     *            the path to cryptographic policy properties file.
     * @param key
     *            the key used to retrieve properties from the properties input.
     * @throws CryptoLibException
     *             if {@code path} or {@code key} is invalid.
     */
    public ScytlKeyStorePolicyFromProperties(final String path,
            final String key)
            throws CryptoLibException {

        PolicyFromPropertiesHelper helper =
            new PolicyFromPropertiesHelper(path);

        String trimmedKey = key.trim();

        _storeTypeAndProvider = ConfigScytlKeyStoreTypeAndProvider
            .valueOf(helper.getNotBlankPropertyValue(
                String.format("scytl.keystore.%s", trimmedKey)));

        _kdfDerivationParameters = ConfigKDFDerivationParameters
            .valueOf(helper.getNotBlankPropertyValue(
                String.format("primitives.kdfderivation.%s", trimmedKey)));

        _pbkdfDerivationParameters = ConfigPBKDFDerivationParameters
            .valueOf(helper.getNotBlankPropertyValue(String
                .format("primitives.pbkdfderivation.%s", trimmedKey)));

        _secureRandomAlgorithmAndProvider =
            ConfigSecureRandomAlgorithmAndProvider
                .valueOf(helper.getNotBlankOSDependentPropertyValue(String
                    .format("primitives.pbkdfderivation.securerandom.%s",
                        trimmedKey)));

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

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

    @Override
    public ConfigScytlKeyStoreTypeAndProvider getStoreTypeAndProvider() {
        return _storeTypeAndProvider;
    }

    @Override
    public ConfigKDFDerivationParameters getKDFDerivationParameters() {
        return _kdfDerivationParameters;
    }

    @Override
    public ConfigPBKDFDerivationParameters getPBKDFDerivationParameters() {
        return _pbkdfDerivationParameters;
    }

    public ConfigSecureRandomAlgorithmAndProvider getSecureRandomAlgorithmAndProvider() {
        return _secureRandomAlgorithmAndProvider;
    }

    public ConfigSecretKeyAlgorithmAndSpec getSecretKeyAlgorithmAndSpec() {
        return _secretKeyAlgorithmAndSpec;
    }

    public ConfigSymmetricCipherAlgorithmAndSpec getSymmetricCipherAlgorithmAndSpec() {
        return _symmetricCipherAlgorithmAndSpec;
    }
}
