//! Provides functions to get the latest observed scroll speed.
//! For host-side mode, the daemon writes a single numeric value to a stats file.

use std::{
    path::PathBuf,
    sync::atomic::{AtomicU64, Ordering},
    thread::{self, JoinHandle},
    time::Duration,
};

static INPUT_SPEED_BITS: AtomicU64 = AtomicU64::new(0);

pub fn read_input_speed() -> f64 {
    f64::from_bits(INPUT_SPEED_BITS.load(Ordering::Relaxed))
}

pub fn setup_input_speed_reader() -> JoinHandle<anyhow::Result<()>> {
    thread::spawn(|| {
        let path = stats_path();

        loop {
            let stale = std::fs::metadata(&path)
                .and_then(|m| m.modified())
                .ok()
                .and_then(|t| t.elapsed().ok())
                .map(|age| age > Duration::from_millis(300))
                .unwrap_or(true);

            if stale {
                INPUT_SPEED_BITS.store(0.0f64.to_bits(), Ordering::Relaxed);
            } else if let Ok(content) = std::fs::read_to_string(&path)
                && let Ok(parsed) = content.trim().parse::<f64>()
            {
                INPUT_SPEED_BITS.store(parsed.to_bits(), Ordering::Relaxed);
            }

            thread::sleep(Duration::from_millis(75));
        }
    })
}

fn stats_path() -> PathBuf {
    if let Ok(path) = std::env::var("GSF_STATS_PATH") {
        return PathBuf::from(path);
    }

    // Keep default shared across sudo/non-sudo runs.
    PathBuf::from("/tmp/gsf-speed.txt")
}
