use anyhow::{Context, Result};
use serde::Deserialize;
use std::path::Path;

#[derive(Debug, Clone, Deserialize, PartialEq)]
pub struct CalConfig {
    pub file: String,
    pub name: String,
    pub color: String,
    pub url: Option<String>,
}

#[derive(Debug, Clone, Deserialize, PartialEq)]
pub struct Config {
    #[serde(rename = "cal", default)]
    pub cals: Vec<CalConfig>,
}

pub fn load_config(dir: &Path) -> Result<Config> {
    let path = dir.join("config.toml");
    let content = std::fs::read_to_string(&path)
        .with_context(|| format!("failed to read {}", path.display()))?;
    let config: Config = toml::from_str(&content)?;
    Ok(config)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::fs;
    use std::io::Write;

    fn write_config(dir: &Path, content: &str) {
        let mut f = fs::File::create(dir.join("config.toml")).unwrap();
        f.write_all(content.as_bytes()).unwrap();
    }

    #[test]
    fn test_load_config_with_url() {
        let dir = tempfile::tempdir().unwrap();
        write_config(
            dir.path(),
            r#"
[[cal]]
file = "work.ics"
name = "Work"
color = "blue"
url = "https://example.com/work.ics"

[[cal]]
file = "family.ics"
name = "Family"
color = "green"
"#,
        );
        let config = load_config(dir.path()).unwrap();
        assert_eq!(config.cals.len(), 2);
        assert_eq!(config.cals[0].file, "work.ics");
        assert_eq!(config.cals[0].name, "Work");
        assert_eq!(config.cals[0].color, "blue");
        assert_eq!(
            config.cals[0].url,
            Some("https://example.com/work.ics".to_string())
        );
        assert_eq!(config.cals[1].url, None);
    }

    #[test]
    fn test_load_config_empty_cals() {
        let dir = tempfile::tempdir().unwrap();
        write_config(dir.path(), "");
        let config = load_config(dir.path()).unwrap();
        assert!(config.cals.is_empty());
    }

    #[test]
    fn test_load_config_file_not_found() {
        let dir = tempfile::tempdir().unwrap();
        let result = load_config(dir.path());
        assert!(result.is_err());
    }
}
