package app.closer.data.local

import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys
import java.security.KeyStore

object SecurePreferencesFactory {
    private const val TAG = "SecurePreferences"
    private const val ANDROID_KEYSTORE = "AndroidKeyStore"
    private const val MASTER_KEY_ALIAS = "_androidx_security_master_key_"

    fun encryptedSharedPreferences(
        context: Context,
        prefsName: String
    ): SharedPreferences {
        val appContext = context.applicationContext
        return runCatching {
            create(appContext, prefsName)
        }.getOrElse { firstError ->
            Log.w(TAG, "Resetting unreadable encrypted preferences: $prefsName", firstError)
            reset(appContext, prefsName)
            create(appContext, prefsName)
        }
    }

    private fun create(context: Context, prefsName: String): SharedPreferences {
        val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
        return EncryptedSharedPreferences.create(
            prefsName,
            masterKeyAlias,
            context,
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
        )
    }

    private fun reset(context: Context, prefsName: String) {
        context.deleteSharedPreferences(prefsName)
        context.deleteSharedPreferences(MASTER_KEY_ALIAS)
        runCatching {
            val keyStore = KeyStore.getInstance(ANDROID_KEYSTORE).apply { load(null) }
            if (keyStore.containsAlias(prefsName)) {
                keyStore.deleteEntry(prefsName)
            }
            if (keyStore.containsAlias(MASTER_KEY_ALIAS)) {
                keyStore.deleteEntry(MASTER_KEY_ALIAS)
            }
        }.onFailure { error ->
            Log.w(TAG, "Could not delete Android Keystore master key.", error)
        }
    }
}
