use std::{time::{SystemTime}};

// by hzsong, 2023-0408
/// elapsed timer base on std::time::SystemTime
pub struct Ellapse {
    start: SystemTime,
    list_ticks: Vec<(String, i64)>,
    micros_all: i64,
}

impl Ellapse {
    pub fn new() -> Self{
        Ellapse {
            start: SystemTime::now(),
            list_ticks: vec![],
            micros_all: 0
        }
    }
    /// tick onetime
    /// return: micros of this tick
    pub fn tick(&mut self, tick_name: &str) -> i64 {
        let last_nanos_all = self.micros_all;
        self.micros_all = self.start.elapsed().unwrap_or_default().as_micros() as i64;
        let micros_thistick = self.micros_all - last_nanos_all;
        self.list_ticks.push((tick_name.to_string(), micros_thistick));

        micros_thistick
    }

    pub fn micros_all(&self) -> i64 {
        self.micros_all
    }


    pub fn list_ticks(&self) -> &Vec<(String, i64)> {
        &self.list_ticks
    }

}
#[test]
fn test_20230408() {
    use std::time::Duration;
    
    let mut 耗时计时器 = Ellapse::new();
    std::thread::sleep(Duration::from_secs(1));
    println!("耗时1秒: {}", 耗时计时器.tick("1秒"));
    std::thread::sleep(Duration::from_secs(2));
    println!("耗时2秒: {}", 耗时计时器.tick("2秒"));
    println!("总耗时: {}", 耗时计时器.micros_all() as f64 / 1000_000_f64);
    println!("耗时详情: {:?}", 耗时计时器.list_ticks());



}

#[test]
fn test_毫秒转字符串_20230408() {
    {
        let millis = 9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
        let millis = 9_9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
        let millis = 99_9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
        let millis = 999_9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
        let millis = 9999_9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
        let millis = 9_9999_9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
        let millis = 19_9999_9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
    }
    {
        let millis = -9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
        let millis = -9_9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
        let millis = -99_9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
        let millis = -999_9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
        let millis = -9999_9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
        let millis = -9_9999_9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
        let millis = -19_9999_9999;
        println!("毫秒转字符串: {millis} => {}", format_mills(millis));
    }
}


pub fn format_mills(millis: i32) -> String {
    let (prefix , millis_abs) = if millis < 0 {
        ("before", -millis)
    } else {
        ("after", millis)
    };
    if millis_abs < 10_000 {
        return format!("{prefix} {millis_abs} millsecs");
    }
    let seconds = millis_abs as f64 / 1000_f64;
    if seconds < 100.0 {
        return format!("{prefix} {:.1} seconds", seconds);
    }
    let minutes = seconds / 60_f64;
    if minutes < 100.0 {
        return format!("{prefix} {:.1} minutes", minutes);
    }
    let hours = minutes / 60_f64;
    if hours < 100.0 {
        return format!("{prefix} {:.1} hours", hours);
    }
    let days = hours / 24_f64;
    format!("{prefix} {:.1} days", days)
}

