package com.airlock.iam.security.util.crypto;

import com.google.common.base.Preconditions;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Objects;

public final class PBEStringCipherHelper {
   public static final String ENCRYPTED_PREFIX = "[ENC:SHA1/AES]";
   private static final Charset ENCODING = StandardCharsets.UTF_8;
   private static final PBEWithSHA1andAES CIPHER = PBEWithSHA1andAES.createStaticCipher(32000);

   private PBEStringCipherHelper() {
   }

   public static String encrypt(String plaintext, char[] password) throws EncryptionException {
      Objects.requireNonNull(plaintext);
      Objects.requireNonNull(password);
      Preconditions.checkArgument(password.length > 0);
      byte[] cipherBytes = CIPHER.encrypt(new String(password), plaintext.getBytes(ENCODING));
      return "[ENC:SHA1/AES]" + Base64.getEncoder().encodeToString(cipherBytes);
   }

   public static String decrypt(String ciphertext, char[] password) throws DecryptionException {
      Objects.requireNonNull(ciphertext);
      Objects.requireNonNull(password);
      Preconditions.checkArgument(password.length > 0);
      if (isEncryptedString(ciphertext)) {
         byte[] cipherBytes = Base64.getDecoder().decode(removeEncryptedPrefix(ciphertext));
         byte[] plainBytes = CIPHER.decrypt(new String(password), cipherBytes);
         return new String(plainBytes, ENCODING);
      } else {
         return ciphertext;
      }
   }

   private static String removeEncryptedPrefix(String ciphertext) {
      return ciphertext.startsWith("[ENC:SHA1/AES]") ? ciphertext.substring("[ENC:SHA1/AES]".length()) : ciphertext;
   }

   private static boolean isEncryptedString(String ciphertext) {
      return ciphertext.startsWith("[ENC:SHA1/AES]");
   }
}
