use anyhow::Result;
use clap::Parser;
use gpg_tui::app::handler;
use gpg_tui::app::launcher::App;
use gpg_tui::args::Args;
use gpg_tui::config::Config;
use gpg_tui::gpg::config::GpgConfig;
use gpg_tui::gpg::context::GpgContext;
use gpg_tui::term::event::{Event, EventHandler};
use gpg_tui::term::tui::Tui;
use gpg_tui::GPGME_REQUIRED_VERSION;
use log::LevelFilter;
use ratatui::backend::CrosstermBackend;
use ratatui::Terminal;
use std::env;
use std::io::{self, Write};
use std::str::FromStr;
use tui_logger::TuiLoggerFile;
fn main() -> Result<()> {
let mut args = Args::parse();
let config = if let Some(config_file) =
args.config.to_owned().or_else(Config::get_default_location)
{
let config = Config::parse_config(&config_file)?;
args = config.update_args(args);
config
} else {
Config::default()
};
tui_logger::init_logger(if let Ok(log_level) = env::var("RUST_LOG") {
LevelFilter::from_str(&log_level)?
} else {
LevelFilter::Trace
})?;
tui_logger::set_default_level(LevelFilter::Trace);
if let Some(ref log_file) = args.log_file {
let file_options = TuiLoggerFile::new(log_file);
tui_logger::set_log_file(file_options);
}
log::debug!(target: "args", "{:?}", args);
log::debug!(target: "config", "{:?}", config);
let custom_key_bindings = config
.general
.unwrap_or_default()
.key_bindings
.unwrap_or_default();
let gpg_config = GpgConfig::new(&args)?;
log::warn!(target: "gpg", "checking gpgme version: {:?}", GPGME_REQUIRED_VERSION);
gpg_config.check_gpgme_version(GPGME_REQUIRED_VERSION);
let mut gpgme = GpgContext::new(gpg_config)?;
let mut app = App::new(&mut gpgme, &args)?;
let backend = CrosstermBackend::new(io::stderr());
let terminal = Terminal::new(backend)?;
let events = EventHandler::new(args.tick_rate);
let mut tui = Tui::new(terminal, events);
tui.init()?;
while app.state.running {
tui.draw(&mut app)?;
match tui.events.next()? {
Event::Key(key_event) => handler::handle_events(
key_event,
&custom_key_bindings,
&mut tui,
&mut app,
)?,
Event::Tick => app.tick(),
_ => {}
}
}
Tui::<CrosstermBackend<io::Stderr>>::reset()?;
if let Some(message) = app.state.exit_message {
writeln!(io::stdout(), "{message}")?;
}
Ok(())
}