//! Crypto utilities for the vault crate

//! Crypto utilities for the vault crate
use chacha20poly1305::{ChaCha20Poly1305, KeyInit as ChaChaKeyInit, aead::{Aead, generic_array::GenericArray}};

use pbkdf2::pbkdf2_hmac;

use sha2::Sha256;
use rand_core::{RngCore, OsRng as RandOsRng};

pub mod kdf {
    use super::*;

    /// Standard parameters for keyspace key derivation
    pub const KEYSPACE_KEY_LENGTH: usize = 32;
    pub const KEYSPACE_KEY_ITERATIONS: u32 = 10_000;
    
    /// Derive a symmetric key for keyspace operations using standard parameters
    /// Always uses PBKDF2 with SHA-256, 32 bytes output, and 10,000 iterations
    pub fn keyspace_key(password: &[u8], salt: &[u8]) -> Vec<u8> {
        derive_key_pbkdf2(password, salt, KEYSPACE_KEY_LENGTH, KEYSPACE_KEY_ITERATIONS)
    }

    pub fn derive_key_pbkdf2(password: &[u8], salt: &[u8], key_len: usize, iterations: u32) -> Vec<u8> {
        let mut key = vec![0u8; key_len];
        pbkdf2_hmac::<Sha256>(password, salt, iterations, &mut key);
        key
    }
}

pub mod cipher {
    use super::*;


    pub fn encrypt_chacha20(key: &[u8], plaintext: &[u8], nonce: &[u8]) -> Result<Vec<u8>, String> {
        let cipher = ChaCha20Poly1305::new(GenericArray::from_slice(key));
        cipher.encrypt(GenericArray::from_slice(nonce), plaintext)
            .map_err(|e| format!("encryption error: {e}"))
    }

    pub fn decrypt_chacha20(key: &[u8], ciphertext: &[u8], nonce: &[u8]) -> Result<Vec<u8>, String> {
        let cipher = ChaCha20Poly1305::new(GenericArray::from_slice(key));
        cipher.decrypt(GenericArray::from_slice(nonce), ciphertext)
            .map_err(|e| format!("decryption error: {e}"))
    }

    

    
}

pub fn random_salt(len: usize) -> Vec<u8> {
    let mut salt = vec![0u8; len];
    RandOsRng.fill_bytes(&mut salt);
    salt
}
