package com.airlock.iam.common.infrastructure.state.redis;

import com.airlock.iam.base.api.domain.model.plugin.LogicForConfig;
import com.airlock.iam.common.application.configuration.state.Aes128GcmStateEncryptionConfig;
import com.airlock.iam.elog.api.EDefaultLogType;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.security.util.crypto.Aes128GcmCipher;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.Optional;
import org.apache.commons.lang3.Strings;

@LogicForConfig(Aes128GcmStateEncryptionConfig.class)
public final class Aes128GcmStateEncryption implements StateEncryption {
   private static final ELogger LOG = ELoggerFactory.getLogger(Aes128GcmStateEncryption.class);
   private static final String ENCRYPTED_PREFIX = "[ENC:AES128_GCM]";
   private final Provider<Aes128GcmCipher> cipher;

   @Inject
   public Aes128GcmStateEncryption(Provider<Aes128GcmCipher> cipher) {
      this.cipher = cipher;
   }

   @Override
   public String encrypt(String plaintext) {
      return "[ENC:AES128_GCM]" + ((Aes128GcmCipher)this.cipher.get()).encrypt(plaintext);
   }

   @Override
   public Optional<String> decrypt(String ciphertext) {
      if (!this.canDecrypt(ciphertext)) {
         LOG.warn(EDefaultLogType.GENERIC_LOG_TYPE, "String to decrypt is not marked as ciphertext.");
         return Optional.empty();
      } else {
         return ((Aes128GcmCipher)this.cipher.get()).decrypt(Strings.CS.removeStart(ciphertext, "[ENC:AES128_GCM]"));
      }
   }

   @Override
   public boolean canDecrypt(String ciphertext) {
      return ciphertext.startsWith("[ENC:AES128_GCM]");
   }
}
