use crate::encryption::encryption_flow::{decrypt_stream, encrypt_stream};
use crate::encryption::encryption_primitives::generate_nonce;
use crate::encryption::file::read_file;
use crate::errors::EnkryptitError;
use crate::key::EnkryptitKey;
use crate::metadatas::{ArchiveHeader, MetaDatas};
use crate::types::CompressionType;
use gradient_bar::GradientProgressBar;
use std::io::{BufWriter, Write};
use std::io::{Seek, SeekFrom};
use zeroize::Zeroize;
pub fn encrypt_file_single(
path: &str,
compression: CompressionType,
enkryptit_key: EnkryptitKey,
) -> Result<String, EnkryptitError> {
let file = read_file(path)?;
let mut master_nonce = generate_nonce();
let metadata = MetaDatas::new(
enkryptit_key.key_type_as_ref().clone(),
compression,
master_nonce,
)
.pack()?;
let encrypted_path = format!("{}.encky", path);
let cipherfile = std::fs::File::create(&encrypted_path)?;
let mut writer = BufWriter::new(cipherfile);
let actual_meta_len = metadata.len() as u32;
let header = ArchiveHeader::new(false, actual_meta_len).pack()?;
writer.write_all(&[header.len() as u8])?;
writer.write_all(&header)?;
writer.write_all(&metadata)?;
let progress_bar = GradientProgressBar::with_total_bytes(file.len, "Encrypting...");
let _ = encrypt_stream(
&mut writer,
file.reader,
master_nonce,
enkryptit_key.key_as_ref(),
compression,
Some(progress_bar),
)?;
master_nonce.zeroize();
writer.flush()?;
Ok(encrypted_path)
}
pub fn decrypt_file_single(
path: &str,
payload_offset: u64,
enkryptit_key: EnkryptitKey,
master_nonce: [u8; 24],
compression: CompressionType,
) -> Result<String, EnkryptitError> {
let mut file = read_file(path)?;
let plain_path = path.strip_suffix(".encky").unwrap_or(path);
let new_file = std::fs::File::create(plain_path)?;
let mut writer = BufWriter::new(new_file);
file.reader.seek(SeekFrom::Start(payload_offset))?;
let progress_bar = GradientProgressBar::with_total_bytes(file.len, "Decrypting...");
let _ = decrypt_stream(
&mut writer,
file.reader,
enkryptit_key.key_as_ref(),
compression,
master_nonce,
Some(progress_bar),
)?;
writer.flush()?;
Ok(plain_path.to_string())
}