/*
 * 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.products.ov.config.commands.voters.datapacks.generators;

import java.io.IOException;
import java.math.BigInteger;

import com.scytl.cryptolib.api.asymmetric.AsymmetricServiceAPI;
import com.scytl.cryptolib.api.elgamal.ElGamalServiceAPI;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.api.scytl.keystore.ScytlKeyStoreServiceAPI;
import com.scytl.cryptolib.elgamal.bean.ElGamalEncryptionParameters;
import com.scytl.cryptolib.elgamal.bean.ElGamalPrivateKey;
import com.scytl.cryptolib.scytl.keystore.factory.CryptoScytlKeyStoreWithPBKDF;
import com.scytl.cryptolib.scytl.keystore.service.ScytlKeyStoreService;
import com.scytl.cryptolib.securerandom.cryptoapi.CryptoAPIRandomString;
import com.scytl.products.ov.commons.beans.EncryptionParameters;
import com.scytl.products.ov.datapacks.generators.CredentialDataPackGenerator;
import com.scytl.products.ov.datapacks.generators.X509CertificateGenerator;

public class ElGamalCredentialDataPackGenerator extends CredentialDataPackGenerator {

    protected final ElGamalServiceAPI elGamalService;

    public ElGamalCredentialDataPackGenerator(final AsymmetricServiceAPI asymmetricService,
            final CryptoAPIRandomString cryptoRandomString, final X509CertificateGenerator certificateGenerator,
            final ScytlKeyStoreServiceAPI storesService, final ElGamalServiceAPI elGamalService) {
        super(asymmetricService, cryptoRandomString, certificateGenerator, storesService);

        this.elGamalService = elGamalService;
    }

    protected CryptoScytlKeyStoreWithPBKDF createCryptoKeyStoreWithPBKDF() {

        ScytlKeyStoreServiceAPI service;
        try {
            service = new ScytlKeyStoreService();
        } catch (GeneralCryptoLibException e) {
            throw new IllegalStateException("Failed to create a key store.", e);
        }
        return (CryptoScytlKeyStoreWithPBKDF) service.createKeyStore();
    }

    protected ElGamalEncryptionParameters adaptEncParams(final EncryptionParameters encryptionParametersFromHolder)
            throws IOException {

        final BigInteger p = new BigInteger(encryptionParametersFromHolder.getP());
        final BigInteger q = new BigInteger(encryptionParametersFromHolder.getQ());
        final BigInteger g = new BigInteger(encryptionParametersFromHolder.getG());

        ElGamalEncryptionParameters returnedParams;

        try {
            returnedParams = new ElGamalEncryptionParameters(p, q, g);
        } catch (final GeneralCryptoLibException e) {
            throw new IOException(
                "An error occurred while adapting the received encryption parameters.", e);
        }

        return returnedParams;
    }

    protected void putKeyInKeystore(final CryptoScytlKeyStoreWithPBKDF keyStore, final ElGamalPrivateKey privateKey,
            final char[] keyStorePassword, final String alias) throws GeneralCryptoLibException {

        keyStore.setElGamalPrivateKeyEntry(alias, privateKey, keyStorePassword);
    }
}
