speedtest-tui 0.1.1

A terminal-based network speed test tool with real-time gauges and graphs
use anyhow::Result;
use std::path::PathBuf;

use crate::config::Config;
use crate::network::SpeedTestResult;

const MAX_HISTORY_ENTRIES: usize = 1000;

pub fn history_path() -> Result<PathBuf> {
    Ok(Config::config_dir()?.join("history.json"))
}

pub fn load_history() -> Result<Vec<SpeedTestResult>> {
    let path = history_path()?;
    if !path.exists() {
        return Ok(Vec::new());
    }
    let content = std::fs::read_to_string(&path)?;
    let history: Vec<SpeedTestResult> = serde_json::from_str(&content)?;
    Ok(history)
}

pub fn save_history(history: &[SpeedTestResult]) -> Result<()> {
    let path = history_path()?;
    if let Some(parent) = path.parent() {
        std::fs::create_dir_all(parent)?;
    }
    let content = serde_json::to_string_pretty(history)?;
    std::fs::write(path, content)?;
    Ok(())
}

pub fn add_to_history(result: SpeedTestResult) -> Result<()> {
    let mut history = load_history()?;
    history.push(result);

    if history.len() > MAX_HISTORY_ENTRIES {
        history = history.split_off(history.len() - MAX_HISTORY_ENTRIES);
    }

    save_history(&history)?;
    Ok(())
}

pub fn clear_history() -> Result<()> {
    let path = history_path()?;
    if path.exists() {
        std::fs::remove_file(path)?;
    }
    Ok(())
}

#[allow(dead_code)]
pub fn get_last_result() -> Result<Option<SpeedTestResult>> {
    let history = load_history()?;
    Ok(history.into_iter().last())
}

#[allow(dead_code)]
pub fn get_history_range(
    start: chrono::DateTime<chrono::Utc>,
    end: chrono::DateTime<chrono::Utc>,
) -> Result<Vec<SpeedTestResult>> {
    let history = load_history()?;
    Ok(history
        .into_iter()
        .filter(|r| r.timestamp >= start && r.timestamp <= end)
        .collect())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_history_path() {
        let path = history_path();
        assert!(path.is_ok());
    }
}