use threadpool::ThreadPool;
use std::thread;

/// Thread utility class
pub struct ThreadUtil {
    pool: ThreadPool,
}

impl ThreadUtil {
    /// 创建一个线程池，并执行任务
    ///
    /// # 参数
    /// * `thread_num` - 线程池中的线程数量
    pub fn new(thread_num: usize) -> Self {
        let pool = threadpool::ThreadPool::new(thread_num);
        Self { pool }
    }

    /// 执行一个任务函数
    ///
    /// 该函数将给定的任务提交到线程池中执行。任务必须是只执行一次的闭包，
    /// 并且需要满足线程安全和生命周期要求。
    ///
    /// # 参数
    ///
    /// * `task` - 要执行的任务函数，必须实现FnOnce、Send和'static约束
    ///
    /// # 泛型参数
    ///
    /// * `F` - 任务函数的类型，必须满足FnOnce() + Send + 'static约束
    pub fn execute<F>(&self, task: F)
    where
        F: FnOnce() + Send + 'static,
    {
        // 将任务委托给内部线程池执行
        self.pool.execute(task);
    }

    /// 等待线程池中的所有任务执行完成
    ///
    /// 此函数会阻塞当前线程，直到线程池中的所有任务都执行完毕。
    /// 调用此函数后，线程池将不再接受新的任务。
    pub fn join(&self) {
        self.pool.join();
    }

    pub fn spawn<F, T>(f: F) -> thread::JoinHandle<T>
    where
        F: FnOnce() -> T,
        F: Send + 'static,
        T: Send + 'static,
    {
        thread::spawn(f)
    }
    
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn it_works() {
        let pool_util = ThreadUtil::new(4);
        pool_util.execute(|| {
            println!("Hello, world2!");
        });
        println!("Hello, world1!");
        pool_util.join();
        println!("Hello, world3!");
    }
}
