//! mac-route：一个用 ratatui 实现的 macOS 静态路由 TUI 管理器。
//!
//! 通过 `networksetup` 命令查看/修改附加路由，写操作经 osascript 图形授权提权。

#[macro_use]
mod macros;

mod app;
mod error;
mod event;
mod net;
mod ui;

use std::io;

use app::App;
use crossterm::execute;
use crossterm::terminal::{
    disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
};
use ratatui::backend::CrosstermBackend;
use ratatui::Terminal;

/// 退出 alternate screen / raw mode 的 RAII 守卫。
/// 即便 panic 也能保证终端恢复正常，避免留残屏。
struct TerminalGuard;

impl Drop for TerminalGuard {
    fn drop(&mut self) {
        let _ = restore_terminal();
    }
}

fn setup_terminal() -> io::Result<Terminal<CrosstermBackend<io::Stdout>>> {
    enable_raw_mode()?;
    let mut stdout = io::stdout();
    execute!(stdout, EnterAlternateScreen)?;
    let backend = CrosstermBackend::new(stdout);
    Terminal::new(backend)
}

fn restore_terminal() -> io::Result<()> {
    let mut stdout = io::stdout();
    execute!(stdout, LeaveAlternateScreen)?;
    disable_raw_mode()?;
    Ok(())
}

fn main() -> anyhow::Result<()> {
    let mut terminal = setup_terminal()?;
    let _guard = TerminalGuard; // 任何情况下退出 main 时恢复终端

    let mut app = App::new();
    // 启动时拉取数据；失败也不退出，把错误塞进日志/弹窗，让用户看到。
    if let Err(e) = app.refresh() {
        app.set_error(e);
    }

    let result = run_event_loop(&mut terminal, &mut app);

    // guard 的 drop 会恢复终端，这里先显式恢复以刷新最后一次渲染
    drop(_guard);

    if let Err(e) = result {
        // 终端已恢复，可以直接打印错误
        eprintln!("错误: {e}");
    }
    Ok(())
}

/// 主事件循环：crossterm 事件 → app.update → 渲染。
fn run_event_loop(
    terminal: &mut Terminal<CrosstermBackend<io::Stdout>>,
    app: &mut App,
) -> anyhow::Result<()> {
    loop {
        terminal.draw(|f| ui::draw(f, app))?;

        let ev = event::next_event()?;
        if !app.handle_event(ev)? {
            break;
        }
    }
    Ok(())
}
