package de.ivu.elect.jee.security;


import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;

public class KeyStoreHandler {

  private static final Logger LOG = LoggerFactory.getLogger(KeyStoreHandler.class);

  public static final String DEFAULT_KEYSTORE_TYPE = "PKCS12";

  public void importRootCertificate(KeyStore keyStore, InputStream is, String alias) throws IOException, CertificateException, KeyStoreException {
    keyStore.deleteEntry(alias);
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    Certificate certificate = cf.generateCertificate(is);
    keyStore.setCertificateEntry(alias, certificate);
  }

  public void saveKeyStore(KeyStore keyStore, String keyStorePath, String keyStorePassword) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
    try (FileOutputStream out = new FileOutputStream(keyStorePath)){
      keyStore.store(out, keyStorePassword.toCharArray());
    }
  }

  public void loadKeyStore(String keyStoreType, String keyStorePassword, InputStream inputStream) throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
    KeyStore.getInstance(keyStoreType).load(inputStream, keyStorePassword.toCharArray());
  }

  public KeyStore loadOrCreateKeyStore(String keyStorePath, String keyStorePassword, String keyStoreType) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
    File file = new File(keyStorePath);
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    if (file.exists()) {
      try (FileInputStream stream = new FileInputStream(file)) {
        keyStore.load(stream, keyStorePassword.toCharArray());
      }
    } else {
      keyStore.load(null, null);
      try (FileOutputStream stream = new FileOutputStream(file)) {
        keyStore.store(stream, keyStorePassword.toCharArray());
      }
    }
    return keyStore;
  }


  public void importPrivatzertifikat(KeyStore keyStore, InputStream inputStream, String password) throws IOException, CertificateException, NoSuchAlgorithmException {
    keyStore.load(inputStream, password.toCharArray());
  }

  public boolean isKeyStoreVorhandenUndNichtLeer(String keyStoreLocation, String keyStorePassword, String keyStoreType) {
    if (StringUtils.isBlank(keyStoreLocation) || StringUtils.isBlank(keyStorePassword)) {
      return false;
    }

    if (StringUtils.isBlank(keyStoreType)) {
      keyStoreType = DEFAULT_KEYSTORE_TYPE;
    }

    if (!new File(keyStoreLocation).exists()) {
      LOG.warn("JVM-KeyStore existiert nicht.");
      return false;
    }

    try {
      KeyStore keyStore = loadOrCreateKeyStore(keyStoreLocation, keyStorePassword, keyStoreType);
      return keyStore.size() > 0;
    } catch (Exception e) {
      LOG.warn("JVM-KeyStore konnte nicht zugegriffen werden."+e.getMessage(), e);
      return false;
    }
  }
}
