lazin 1.0.2

Primarily a dotfiles manager
use std::path::PathBuf;

use clap::Args;
use lazin_error::LazinResult;

use crate::{
    common::{self},
    resolve,
};

/// By default reencrypts files and adds them to `lazin.cache`.
/// Can also be used to decrypt configured module files
#[derive(Args)]
pub(super) struct ManageEncryption {
    #[arg(short = 'd', long = "directory", help = "`lazin` config directory")]
    directory: Option<PathBuf>,
    #[arg(
        short = 'r',
        long = "decrypt",
        help = "Decrypt files from all configured modules"
    )]
    decrypt: bool,
}

impl ManageEncryption {
    pub(super) fn manage(&self) -> LazinResult<()> {
        if !self.decrypt {
            self.reencrypt()
        } else {
            self.decrypt()
        }
    }

    fn reencrypt(&self) -> LazinResult {
        let config = common::parse_config(self.directory.as_deref())?;

        config
            .expanded_modules
            .iter()
            .try_for_each(|m| -> LazinResult {
                m.values.iter().try_for_each(|v| -> LazinResult {
                    if let resolve::module::Encryption::Enabled { recipient } = &v.encryption {
                        let did_encrypt = config
                            .encryption_manager
                            .manage_encryption(&v.source, recipient)?;
                        if did_encrypt {
                            lazin_logger::info!("Encrypted file {}", v.source.display())
                        }
                    };

                    Ok(())
                })
            })?;

        config.encryption_manager.flush_cache()?;

        Ok(())
    }

    fn decrypt(&self) -> LazinResult {
        let config = common::parse_config(self.directory.as_deref())?;

        config
            .expanded_modules
            .iter()
            .try_for_each(|m| -> LazinResult {
                m.values.iter().try_for_each(|v| -> LazinResult {
                    if let resolve::module::Encryption::Enabled { .. } = &v.encryption {
                        config
                            .encryption_manager
                            .manage_decryption(&v.source, None)?;

                        lazin_logger::info!("Decrypted file {}", v.source.display())
                    };

                    Ok(())
                })
            })?;

        config.encryption_manager.flush_cache()?;

        Ok(())
    }
}