use std::sync::Arc;

use crossbeam::atomic::AtomicCell;

use super::TaskExecutor;

/// Simple thread pool
/// Used for quickly submitting tasks
/// Only one thread, bound to only one core
/// 简易线程池
/// 用于快速提交任务
/// 只有一个线程, 只绑定一个核心
pub struct ThreadPoolLite {
    pub thread: TaskExecutor,
}

impl ThreadPoolLite {
    pub fn new() -> ThreadPoolLite {
        let use_core = super::use_last_core("thread_lite");
        let r = ThreadPoolLite {
            thread: TaskExecutor::new(core_affinity::CoreId { id: use_core }, 49),
        };
        r
    }

    pub fn spawn<F>(&self, f: F)
    where
        F: FnOnce(),
        F: Send + 'static,
    {
        self.thread.spawn(|_| f());
    }
}

pub fn _test_thread_lite(test_count: u128) {
    let pool = ThreadPoolLite::new();
    std::thread::sleep(std::time::Duration::from_millis(200));
    let com_time = Arc::new(AtomicCell::new(0_u128));
    for _ in 0..test_count {
        let now = std::time::Instant::now();
        let com_time = com_time.clone();
        pool.spawn(move || {
            // println!("run _test_thread_lite i: {}", i);
            let el = now.elapsed().as_nanos();
            com_time.fetch_add(el);
        });
    }
    println!("------------------------thread_lite 任务提交完成------------------------");
    std::thread::sleep(std::time::Duration::from_secs(1));
    println!(
        "thread_lite test result: Average thread startup time: {:.3} micros\nthread_lite 测试结果: 线程开启平均耗时: {:.3} micros",
        com_time.load() as f64 / test_count as f64 / 1000.0,
        com_time.load() as f64 / test_count as f64 / 1000.0
    );
}

#[test]
pub fn test_cores_count() {
    // 初始化日志
    let _ = env_logger::try_init();

    // 获取核心数并打印
    let cores = crate::fast_thread_pool::CORES.clone();

    // 使用 num_cpus 获取实际的 CPU 数量
    let physical_cpus = num_cpus::get_physical();
    let logical_cpus = num_cpus::get();

    info!(
        "物理CPU数量: {}, 逻辑CPU数量: {}, CORES获取的核心数: {}",
        physical_cpus,
        logical_cpus,
        cores.len()
    );

    // 输出所有核心ID
    info!(
        "核心ID列表: {:?}",
        cores.iter().map(|x| x.id).collect::<Vec<_>>()
    );

    // 验证核心数是否符合预期
    assert!(cores.len() > 0, "核心数应该大于0");
    assert!(
        cores.len() >= physical_cpus,
        "核心数应该大于等于物理CPU数量"
    );

    // 在有超线程技术的系统上，逻辑CPU数通常是物理CPU数的两倍
    if logical_cpus > physical_cpus {
        info!("系统支持超线程技术，每个物理核心有多个逻辑核心");
    }
}
