package com.airlock.iam.admin.infrastructure.service.analytics;

import com.airlock.iam.admin.domain.model.analytics.AnalyticsWrappingKey;
import com.airlock.iam.admin.domain.model.analytics.EncryptedAnalytics;
import com.airlock.iam.base.api.domain.model.exception.FailureException;
import com.airlock.iam.security.util.crypto.Aes128GcmCipher;
import com.airlock.iam.security.util.crypto.RsaCipher;
import jakarta.inject.Inject;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import org.apache.commons.codec.binary.Base64;

public class AnalyticsEncryptionService {
   private static final String KEY_GENERATION_ALGORITHM = "AES";
   private static final int DATA_ENCRYPTION_KEY_SIZE = 256;

   public EncryptedAnalytics encrypt(String usageData, AnalyticsWrappingKey wrappingKey) {
      return this.encryptData(usageData, wrappingKey);
   }

   private EncryptedAnalytics encryptData(String data, AnalyticsWrappingKey wrappingKey) {
      SecretKey dataEncryptionKey = generateKey();
      return new EncryptedAnalytics(encrypt(dataEncryptionKey, data), this.wrapEncryptionKey(dataEncryptionKey, wrappingKey));
   }

   private static SecretKey generateKey() {
      KeyGenerator keyGen;
      try {
         keyGen = KeyGenerator.getInstance("AES");
      } catch (NoSuchAlgorithmException e) {
         throw new FailureException(e);
      }

      keyGen.init(256);
      return keyGen.generateKey();
   }

   private static String encrypt(SecretKey dataEncryptionKey, String data) {
      Aes128GcmCipher cipher = new Aes128GcmCipher(Base64.encodeBase64String(dataEncryptionKey.getEncoded()));
      return cipher.encrypt(data);
   }

   private String wrapEncryptionKey(SecretKey dataEncryptionKey, AnalyticsWrappingKey wrappingKey) {
      try {
         return Base64.encodeBase64String(RsaCipher.wrapKey(dataEncryptionKey, wrappingKey.key()));
      } catch (GeneralSecurityException e) {
         throw new FailureException(e);
      }
   }
}
