package no.zyon.shade.backup

import no.zyon.shade.crypto.CryptoProvider

/**
 * Backup format v1 — passphrase-derived AES-256-GCM blob.
 * Mirror @shade/sdk/backup.ts.
 *
 *   backupKey = HKDF(passphrase_utf8, salt_random_32, info="ShadeBackupKey", 32)
 *   blob      = AES-256-GCM(backupKey, plaintext, no AAD)
 *
 * The stored on-disk form is `{ version, salt(b64), nonce(b64), ciphertext(b64) }`.
 * This file ships only the cryptographic primitives — payload schema and JSON
 * serialization live alongside the high-level SDK and don't need a Kotlin port
 * for vector parity (each platform builds the BackupBlob in its native idiom).
 *
 * NOTE: HKDF is NOT a proper password KDF. The TS SDK acknowledges this and
 * warns users to choose a high-entropy passphrase. When `argon2id` lands in
 * `CryptoProvider`, both ports swap together. Until then, byte-parity for the
 * HKDF + AEAD layer is what V3.5 §sjekkpunkt 8 gates.
 */

private val BACKUP_INFO: ByteArray = "ShadeBackupKey".toByteArray(Charsets.UTF_8)
const val BACKUP_KEY_BYTES = 32
const val BACKUP_VERSION = 1

fun deriveBackupKey(crypto: CryptoProvider, passphrase: String, salt: ByteArray): ByteArray {
    require(passphrase.length >= 12) { "Passphrase must be at least 12 characters" }
    require(salt.size >= 16) { "salt must be at least 16 bytes" }
    return crypto.hkdf(
        passphrase.toByteArray(Charsets.UTF_8),
        salt,
        BACKUP_INFO,
        BACKUP_KEY_BYTES,
    )
}
