use std::{sync::Arc, time::Duration};

use infra::core::{config::config, AppState};
use salvo::{prelude::*, server::ServerHandle};
use tokio::signal::unix::{signal, SignalKind};

use crate::router;

pub async fn run(state: Arc<AppState>) {
    let addr = config().get_string("app.addr").unwrap();

    let acceptor = TcpListener::new(addr).bind().await;
    let mut server = Server::new(acceptor);

    // Sets the MAX_CONCURRENT_STREAMS for HTTP2
    server.http2_mut().max_concurrent_streams(None);

    let handle = server.handle();

    // 创建一个任务来处理信号
    tokio::spawn(shutdown_signal(handle));

    server.serve(router::init(state)).await;
}

async fn shutdown_signal(handle: ServerHandle) {
    let mut sigint = signal(SignalKind::interrupt()).unwrap();
    let mut sigquit = signal(SignalKind::quit()).unwrap();
    let mut sigterm = signal(SignalKind::terminate()).unwrap();

    tokio::select! {
        _ = sigint.recv() => {
            println!("收到 SIGINT 信号，正在关闭服务...");
        }
        _ = sigquit.recv() => {
            println!("收到 SIGQUIT 信号，正在关闭服务...");
        }
        _ = sigterm.recv() => {
            println!("收到 SIGTERM 信号，正在关闭服务...");
        }
    }

    handle.stop_graceful(Duration::from_secs(30));
}
