use serde::Deserialize;
use std::{
    collections::BTreeMap,
    fs,
    path::{Path, PathBuf},
};

#[derive(Debug, Deserialize)]
pub struct HandForceConfig {
    pub thumb: BTreeMap<String, u32>,
    pub index: BTreeMap<String, u32>,
    pub middle: BTreeMap<String, u32>,
    pub ring: BTreeMap<String, u32>,
    pub little: BTreeMap<String, u32>,
}

pub fn try_load_hand_force_config() -> Option<HandForceConfig> {
    let path: PathBuf = std::env::current_exe().ok()?.parent()?.join("config.toml");
    load_hand_force_config(&path)
}

fn load_hand_force_config(path: &Path) -> Option<HandForceConfig> {
    let content = fs::read_to_string(path).ok()?;
    toml::from_str(&content).ok()
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::time::{SystemTime, UNIX_EPOCH};

    #[test]
    fn loads_hand_force_config_toml() {
        let path = std::env::temp_dir().join(format!(
            "eskin-hand-force-config-{}-{}.toml",
            std::process::id(),
            SystemTime::now()
                .duration_since(UNIX_EPOCH)
                .expect("system clock should be after Unix epoch")
                .as_nanos()
        ));
        fs::write(
            &path,
            r#"
                [thumb]
                "0.57" = 35694
                "2.57" = 226640

                [index]
                "0.57" = 45490

                [middle]
                "0.57" = 51562

                [ring]
                "0.57" = 33213

                [little]
                "0.57" = 44291
            "#,
        )
        .expect("test config should be writable");

        let config = load_hand_force_config(&path).expect("valid TOML should load");
        fs::remove_file(&path).expect("test config should be removable");

        assert_eq!(config.thumb["2.57"], 226640);
        assert_eq!(config.index["0.57"], 45490);
    }
}
