package com.github.nullptroma.wallenc.domain.encrypt

import com.github.nullptroma.wallenc.domain.encrypt.Encryptor.Companion.AES_SETTINGS
import kotlinx.coroutines.DisposableHandle
import javax.crypto.Cipher
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi

class EncryptorWithStaticIv(private var secretKey: SecretKey, iv: ByteArray) : DisposableHandle {
    private val ivSpec = IvParameterSpec(iv)

    @OptIn(ExperimentalEncodingApi::class)
    fun encryptString(str: String): String {
        val bytesToEncrypt = str.toByteArray(Charsets.UTF_8)
        val encryptedBytes = encryptBytes(bytesToEncrypt)
        return Base64.encode(encryptedBytes).replace("/", ".")
    }

    @OptIn(ExperimentalEncodingApi::class)
    fun decryptString(str: String): String {
        val bytesToDecrypt = Base64.decode(str.replace(".", "/"))
        val decryptedBytes = decryptBytes(bytesToDecrypt)
        return String(decryptedBytes, Charsets.UTF_8)
    }

    fun encryptBytes(bytes: ByteArray): ByteArray {
        if(secretKey.isDestroyed)
            throw Exception("Object was destroyed")
        val cipher = Cipher.getInstance(AES_SETTINGS)
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec)
        val encryptedBytes = cipher.doFinal(bytes) // зашифрованные байты
        return encryptedBytes
    }

    fun decryptBytes(bytes: ByteArray): ByteArray {
        if(secretKey.isDestroyed)
            throw Exception("Object was destroyed")
        val cipher = Cipher.getInstance(AES_SETTINGS)
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec)
        val decryptedBytes = cipher.doFinal(bytes)
        return decryptedBytes
    }

    override fun dispose() {
        secretKey.destroy()
    }
}