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.MigratingStateEncryptionConfig;
import com.airlock.iam.elog.api.EDefaultLogType;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.Optional;

@LogicForConfig(MigratingStateEncryptionConfig.class)
public class MigratingStateEncryption implements StateEncryption {
   private static final ELogger LOG = ELoggerFactory.getLogger(MigratingStateEncryption.class);
   private final Provider<MigratingStateEncryptionSettings> settings;

   @Inject
   public MigratingStateEncryption(Provider<MigratingStateEncryptionSettings> settings) {
      this.settings = settings;
   }

   @Override
   public String encrypt(String plaintext) {
      return ((MigratingStateEncryptionSettings)this.settings.get()).newEncryption().encrypt(plaintext);
   }

   @Override
   public Optional<String> decrypt(String ciphertext) {
      if (((MigratingStateEncryptionSettings)this.settings.get()).newEncryption().canDecrypt(ciphertext)) {
         Optional<String> plaintext = ((MigratingStateEncryptionSettings)this.settings.get()).newEncryption().decrypt(ciphertext);
         if (plaintext.isPresent()) {
            return plaintext;
         }
      }

      if (((MigratingStateEncryptionSettings)this.settings.get()).previousEncryption().canDecrypt(ciphertext)) {
         return ((MigratingStateEncryptionSettings)this.settings.get()).previousEncryption().decrypt(ciphertext);
      }

      LOG.warn(EDefaultLogType.GENERIC_LOG_TYPE, "Neither the new encryption nor the previous could decrypt the ciphertext.");
      return Optional.empty();
   }

   @Override
   public boolean canDecrypt(String ciphertext) {
      return ((MigratingStateEncryptionSettings)this.settings.get()).newEncryption().canDecrypt(ciphertext)
         || ((MigratingStateEncryptionSettings)this.settings.get()).previousEncryption().canDecrypt(ciphertext);
   }
}
