use anyhow::{Context, Result};
use crate::cli::args::{DecryptArgs, EncryptArgs};
use crate::cli::utils::{resolve_optional_password, resolve_password};
pub fn encrypt(args: &EncryptArgs) -> Result<()> {
use printwell::encrypt::{EncryptionAlgorithm, EncryptionOptions, Permissions, encrypt_pdf};
let pdf_data = std::fs::read(&args.input)
.with_context(|| format!("Failed to read input file: {}", args.input))?;
let owner_password = resolve_password(
args.owner_password.as_deref(),
args.owner_password_file.as_deref(),
args.owner_password_env.as_deref(),
"owner password",
)?;
let user_password = resolve_optional_password(
args.user_password.as_deref(),
args.user_password_file.as_deref(),
args.user_password_env.as_deref(),
"user password",
)?;
let permissions = if args.form_perms.allow_all {
Permissions::ALL
} else {
let mut p = Permissions::NONE;
if args.print_perms.allow_print {
p = p | Permissions::PRINT;
}
if args.content_perms.allow_copy {
p = p | Permissions::COPY;
}
if args.edit_perms.allow_modify {
p = p | Permissions::MODIFY;
}
if args.edit_perms.allow_annotate {
p = p | Permissions::ANNOTATE;
}
if args.form_perms.allow_fill_forms {
p = p | Permissions::FILL_FORMS;
}
if args.content_perms.allow_accessibility {
p = p | Permissions::EXTRACT_ACCESSIBILITY;
}
if args.edit_perms.allow_assemble {
p = p | Permissions::ASSEMBLE;
}
if args.print_perms.allow_print_hq {
p = p | Permissions::PRINT_HIGH_QUALITY;
}
p
};
let algorithm = match args.algorithm.to_lowercase().as_str() {
"aes256" | "aes-256" => EncryptionAlgorithm::Aes256,
"aes128" | "aes-128" => EncryptionAlgorithm::Aes128,
"rc4" | "rc4-128" => EncryptionAlgorithm::Rc4_128,
_ => anyhow::bail!(
"Invalid encryption algorithm: {}. Use: aes256, aes128, or rc4",
args.algorithm
),
};
let options = EncryptionOptions {
owner_password,
user_password,
permissions,
algorithm,
encrypt_metadata: true,
};
let result = encrypt_pdf(&pdf_data, &options).context("Failed to encrypt PDF")?;
result
.write_to_file(&args.output)
.with_context(|| format!("Failed to write encrypted PDF to: {}", args.output))?;
eprintln!("Encrypted PDF written to: {}", args.output);
Ok(())
}
pub fn decrypt(args: &DecryptArgs) -> Result<()> {
use printwell::encrypt::decrypt_pdf;
let pdf_data = std::fs::read(&args.input)
.with_context(|| format!("Failed to read input file: {}", args.input))?;
let password = resolve_password(
args.password.as_deref(),
args.password_file.as_deref(),
args.password_env.as_deref(),
"decryption password",
)?;
let decrypted = decrypt_pdf(&pdf_data, &password)
.context("Decryption failed - incorrect password or corrupted file")?;
std::fs::write(&args.output, &decrypted)
.with_context(|| format!("Failed to write decrypted PDF to: {}", args.output))?;
eprintln!("Decrypted PDF written to: {}", args.output);
Ok(())
}