use std::path::Path;
use std::path::PathBuf;
use std::env;
use std::process::Command;
use anyhow::{Result, Error};

#[derive(Debug, Clone, PartialEq)]
pub enum BackendType {
    Nfs4,
    Fskit,
}

impl BackendType {
    pub fn name(&self) -> &'static str {
        match self {
            BackendType::Nfs4 => "nfs",
            BackendType::Fskit => "fskit",
        }
    }
    
    pub fn supports_macos_version(&self, version: &str) -> bool {
        match self {
            BackendType::Nfs4 => true,
            BackendType::Fskit => version.starts_with("26"),
        }
    }
}

pub fn detect_macos_version() -> String {
    env::var("MACOS_VERSION").unwrap_or_else(|_| {
        let output = Command::new("sw_vers")
            .arg("-productVersion")
            .output()
            .expect("Failed to get macOS version");
        String::from_utf8_lossy(&output.stdout).trim().to_string()
    })
}

pub fn select_backend() -> BackendType {
    let version = detect_macos_version();
    
    if version.starts_with("26") {
        BackendType::Fskit
    } else {
        BackendType::Nfs4
    }
}

pub fn select_backend_manual(backend_name: &str) -> Result<BackendType> {
    match backend_name {
        "nfs" | "nfs4" => Ok(BackendType::Nfs4),
        "fskit" => Ok(BackendType::Fskit),
        _ => Err(Error::msg(format!("Unknown backend: {}", backend_name))),
    }
}

pub fn detect_fuse_t_binary() -> bool {
    Path::new("/Library/Application Support/fuse-t/bin/go-nfsv4").exists()
}

pub fn get_fuse_t_path() -> Option<PathBuf> {
    if detect_fuse_t_binary() {
        Some(PathBuf::from("/Library/Application Support/fuse-t/bin/go-nfsv4"))
    } else {
        None
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_backend_type_name() {
        assert_eq!(BackendType::Nfs4.name(), "nfs");
        assert_eq!(BackendType::Fskit.name(), "fskit");
    }
    
    #[test]
    fn test_backend_support() {
        assert!(BackendType::Nfs4.supports_macos_version("25.0"));
        assert!(BackendType::Nfs4.supports_macos_version("26.0"));
        assert!(!BackendType::Fskit.supports_macos_version("25.0"));
        assert!(BackendType::Fskit.supports_macos_version("26.0"));
    }
    
    #[test]
    fn test_select_backend_macos_26() {
        env::set_var("MACOS_VERSION", "26.4.1");
        let backend = select_backend();
        assert_eq!(backend, BackendType::Fskit);
        env::remove_var("MACOS_VERSION");
    }
    
    #[test]
    fn test_select_backend_macos_25() {
        env::set_var("MACOS_VERSION", "25.0.0");
        let backend = select_backend();
        assert_eq!(backend, BackendType::Nfs4);
        env::remove_var("MACOS_VERSION");
    }
    
    #[test]
    fn test_manual_backend_selection() {
        assert!(select_backend_manual("nfs").is_ok());
        assert!(select_backend_manual("fskit").is_ok());
        assert!(select_backend_manual("invalid").is_err());
    }
    
    #[test]
    fn test_fuse_t_binary_detection() {
        // Should detect FUSE-T binary after installation
        let detected = detect_fuse_t_binary();
        assert!(detected); // Expected to be true after installation
    }
}