use crate::{
    state::StateStore,
    termination::{create_termination, Interrupted},
    ui::{AppRouter, UiManager},
};

mod state;
mod termination;
mod ui;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let (terminator, mut interrupt_rx) = create_termination();
    let (state_store, state_rx) = StateStore::new();
    let (ui_manager, action_rx) = UiManager::new();

    tokio::try_join!(
        state_store.main_loop(terminator, action_rx, interrupt_rx.resubscribe()),
        ui_manager.main_loop::<AppRouter>(state_rx, interrupt_rx.resubscribe()),
    )?;

    if let Ok(reason) = interrupt_rx.recv().await {
        match reason {
            Interrupted::UserInt => eprintln!("exited per user request"),
            Interrupted::OsSigInt => eprintln!("exited because of OS sigint"),
        }
    } else {
        println!("exited because of an unexpected error");
    }

    Ok(())
}