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

import com.scytl.cryptolib.api.asymmetric.AsymmetricServiceAPI;
import com.scytl.cryptolib.api.stores.StoresServiceAPI;
import com.scytl.cryptolib.api.symmetric.SymmetricServiceAPI;
import com.scytl.cryptolib.asymmetric.service.PollingAsymmetricServiceFactory;
import com.scytl.cryptolib.stores.service.PollingStoresServiceFactory;
import com.scytl.cryptolib.symmetric.service.PollingSymmetricServiceFactory;

import java.security.GeneralSecurityException;

/**
 * A secure logger cryptography provider factory which provides different types of implementations.
 */
public class SecureLoggerCryptographyFactory {

  /**
   * Builds a new instance of the secure logger cryptography provider.
   *
   * @return the provider
   * @throws GeneralSecurityException failed to build the provider.
   */
  public SecureLoggerCryptographyProvider build() throws GeneralSecurityException {
    AsymmetricServiceAPI asymmetricService = new PollingAsymmetricServiceFactory().create();
    SymmetricServiceAPI symmetricService = new PollingSymmetricServiceFactory().create();
    StoresServiceAPI storesService = new PollingStoresServiceFactory().create();
    SecureLoggerCryptographyProvider provider = new CryptolibSecureLoggerCryptographyProvider(
        asymmetricService, symmetricService, storesService);
    provider.init();
    return provider;
  }

  /**
   * Builds a new instance of the secure logger cryptography provider from a given class.
   *
   * @return the provider
   * @throws GeneralSecurityException failed to build the provider.
   */
  public SecureLoggerCryptographyProvider build(final String className)
      throws GeneralSecurityException {
    SecureLoggerCryptographyProvider provider;
    try {
      provider = (SecureLoggerCryptographyProvider) Class.forName(className).newInstance();
      provider.init();
    } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
      throw new GeneralSecurityException(e);
    }
    return provider;
  }
}
