//! A non-interactive systemd password agent for encrypted disk passphrases.
//!
//! This agent watches `/run/systemd/ask-password/` for password requests from
//! cryptsetup and automatically responds with a derived passphrase based on
//! the device's innate ID and a firmware OTP key.

mod cryptsetup;
mod parse;
mod passphrase;
mod password_request;
mod rpifwcrypto;

use std::path::Path;
use std::time::Duration;

use cryptsetup::CryptsetupPassphraseRequest;
use password_request::PasswordRequestWatcher;

const ASK_PASSWORD_DIR: &str = "/run/systemd/ask-password";

fn main() -> Result<(), Box<dyn std::error::Error>> {
    eprintln!("cryptsetup-passphrase-agent starting...");

    let ask_dir = Path::new(ASK_PASSWORD_DIR);
    while !ask_dir.exists() {
        std::thread::sleep(Duration::from_secs(1));
    }

    PasswordRequestWatcher::new(ask_dir)?
        .filter_map(Result::ok)
        .filter_map(|req| CryptsetupPassphraseRequest::try_from(req).ok())
        .for_each(|req| {
            eprintln!("Responding to request for device: {}", req.device());
            match passphrase::derive_passphrase(req.device()) {
                Ok(p) => match req.send_passphrase(&p) {
                    Ok(()) => eprintln!("  Passphrase sent successfully"),
                    Err(e) => eprintln!("  Failed to send: {}", e),
                },
                Err(e) => eprintln!("  Failed to derive passphrase: {}", e),
            }
        });

    Ok(())
}
