use crossterm::cursor::{Hide, Show};
use crossterm::terminal::{
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
};
use std::io::{self, stdout};
use std::panic;
use std::sync::Mutex;
use tracing::info;
use tracing_appender::non_blocking::WorkerGuard;
static LOG_GUARD: Mutex<Option<WorkerGuard>> = Mutex::new(None);
pub fn set_log_guard(guard: WorkerGuard) {
*LOG_GUARD.lock().unwrap() = Some(guard);
}
pub fn flush_log() {
if let Some(guard) = LOG_GUARD.lock().unwrap().take() {
drop(guard);
}
}
pub fn install_panic_hook() {
let original = panic::take_hook();
panic::set_hook(Box::new(move |info| {
tracing::error!(target: "pnc::panic", payload = %info);
flush_log();
let _ = restore();
original(info);
}));
}
pub fn init() -> io::Result<()> {
enable_raw_mode()?;
crossterm::execute!(stdout(), EnterAlternateScreen, Hide)?;
info!(target: "pnc::terminal", "terminal initialized");
Ok(())
}
pub fn restore() -> io::Result<()> {
disable_raw_mode()?;
crossterm::execute!(stdout(), Show, LeaveAlternateScreen)?;
info!(target: "pnc::terminal", "terminal restored");
Ok(())
}