// ==================== 计时器模块 ====================
// 提供计时功能，用于测量代码执行时间
// 支持局部计时器（每次创建新实例）和全局计时器（单例模式）

/// 计时器模块
pub mod timer {
    use once_cell::sync::Lazy;

    // ==================== Timer 结构体 ====================
    // 局部计时器，每次创建会记录新的起始时间

    /// 计时器结构体
    /// 用于测量代码执行时间
    #[derive(Clone)] // 可克隆，可在多个线程间传递
    pub struct Timer {
        start_time: std::time::Instant, // 记录创建时的时刻
    }

    impl Timer {
        /// 创建并启动一个新的计时器
        pub fn start() -> Self {
            Timer {
                start_time: std::time::Instant::now(),
            }
        }

        /// 获取经过的时间（Duration）
        pub fn elapsed(&self) -> std::time::Duration {
            self.start_time.elapsed()
        }

        /// 获取经过的时间（秒，浮点数）
        pub fn elapsed_secs(&self) -> f64 {
            self.start_time.elapsed().as_secs_f64()
        }

        /// 获取格式化的时间字符串
        /// 格式示例：1h 2m 3s, 45m 30s, 30s, 500ms
        pub fn elapsed_format(&self) -> String {
            crate::format_duration(&self.elapsed())
        }

        /// 重置计时器，重新开始计时
        pub fn reset(&mut self) {
            self.start_time = std::time::Instant::now();
        }
    }

    impl std::fmt::Display for Timer {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            write!(f, "{}", self.elapsed_format())
        }
    }

    // ==================== 全局计时器 ====================
    // 程序生命周期内只有一个计时器，用于记录程序总运行时间

    /// 全局计时器单例
    /// 在程序启动时自动开始计时
    static GLOBAL_TIMER: Lazy<Timer> = Lazy::new(|| Timer::start());

    /// 格式化时间间隔为可读字符串
    ///
    /// # 参数
    /// - `duration`: 时间间隔引用
    ///
    /// # 返回格式
    /// - 超过1小时：Xh Xm Xs
    /// - 超过1分钟：Xm Xs
    /// - 超过1秒：X.Xs
    /// - 不足1秒：Xms
    pub fn format_duration(duration: &std::time::Duration) -> String {
        let total_secs = duration.as_secs();
        let hours = total_secs / 3600;
        let minutes = (total_secs % 3600) / 60;
        let secs = total_secs % 60;
        let millis = duration.subsec_millis();

        if hours > 0 {
            format!("{}h {}m {}s", hours, minutes, secs)
        } else if minutes > 0 {
            format!("{}m {}s", minutes, secs)
        } else if secs > 0 {
            if millis > 0 {
                format!("{}.{:03}s", secs, millis)
            } else {
                format!("{}s", secs)
            }
        } else {
            format!("{}ms", duration.as_millis())
        }
    }

    /// 全局计时器管理结构体（单例模式）
    pub struct GlobalTimer;

    impl GlobalTimer {
        /// 获取全局计时器实例引用
        pub fn get_instance() -> &'static Timer {
            &GLOBAL_TIMER
        }

        /// 获取经过的时间（Duration）
        pub fn elapsed() -> std::time::Duration {
            GLOBAL_TIMER.elapsed()
        }

        /// 获取经过的时间（秒，浮点数）
        pub fn elapsed_secs() -> f64 {
            GLOBAL_TIMER.elapsed_secs()
        }

        /// 获取格式化的时间字符串
        pub fn elapsed_format() -> String {
            GLOBAL_TIMER.elapsed_format()
        }
    }
}

pub use timer::{GlobalTimer, Timer, format_duration};
