//! Path helpers for GeoGraphDB sidecar files
//!
//! Provides consistent derivation of sidecar file paths from a base .geo file.
//!
//! Rules:
//! - `base.geo` -> `base.geo.cfg` (CFG data)
//! - `base.geo` -> `base.geo.idx` (index data)
//! - `base.geo` -> `base.geo.complexity` (complexity history)

use std::path::Path;

/// Derive the CFG sidecar path from a base .geo file
///
/// # Examples
/// ```
/// use geographdb_core::storage::paths::geo_cfg_path;
/// use std::path::Path;
///
/// assert_eq!(
///     geo_cfg_path(Path::new("data/file.geo")),
///     Path::new("data/file.geo.cfg")
/// );
/// ```
pub fn geo_cfg_path(base_geo: &Path) -> std::path::PathBuf {
    let mut path = base_geo.as_os_str().to_os_string();
    path.push(".cfg");
    std::path::PathBuf::from(path)
}

/// Derive the index sidecar path from a base .geo file
///
/// # Examples
/// ```
/// use geographdb_core::storage::paths::geo_idx_path;
/// use std::path::Path;
///
/// assert_eq!(
///     geo_idx_path(Path::new("data/file.geo")),
///     Path::new("data/file.geo.idx")
/// );
/// ```
pub fn geo_idx_path(base_geo: &Path) -> std::path::PathBuf {
    let mut path = base_geo.as_os_str().to_os_string();
    path.push(".idx");
    std::path::PathBuf::from(path)
}

/// Derive the complexity history sidecar path from a base .geo file
///
/// # Examples
/// ```
/// use geographdb_core::storage::paths::geo_complexity_path;
/// use std::path::Path;
///
/// assert_eq!(
///     geo_complexity_path(Path::new("data/file.geo")),
///     Path::new("data/file.geo.complexity")
/// );
/// ```
pub fn geo_complexity_path(base_geo: &Path) -> std::path::PathBuf {
    let mut path = base_geo.as_os_str().to_os_string();
    path.push(".complexity");
    std::path::PathBuf::from(path)
}

/// Get all sidecar paths for a base .geo file
pub fn all_sidecar_paths(base_geo: &Path) -> Vec<std::path::PathBuf> {
    vec![
        geo_cfg_path(base_geo),
        geo_idx_path(base_geo),
        geo_complexity_path(base_geo),
    ]
}

// ============================================================================
// TESTS
// ============================================================================

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

    #[test]
    fn test_geo_cfg_path_simple() {
        let base = Path::new("data/file.geo");
        let cfg = geo_cfg_path(base);
        assert_eq!(cfg, Path::new("data/file.geo.cfg"));
    }

    #[test]
    fn test_geo_cfg_path_absolute() {
        let base = Path::new("/home/user/project/code.geo");
        let cfg = geo_cfg_path(base);
        assert_eq!(cfg, Path::new("/home/user/project/code.geo.cfg"));
    }

    #[test]
    fn test_geo_cfg_path_single_component() {
        let base = Path::new("test.geo");
        let cfg = geo_cfg_path(base);
        assert_eq!(cfg, Path::new("test.geo.cfg"));
    }

    #[test]
    fn test_geo_idx_path() {
        let base = Path::new("data/file.geo");
        let idx = geo_idx_path(base);
        assert_eq!(idx, Path::new("data/file.geo.idx"));
    }

    #[test]
    fn test_geo_complexity_path() {
        let base = Path::new("data/file.geo");
        let complexity = geo_complexity_path(base);
        assert_eq!(complexity, Path::new("data/file.geo.complexity"));
    }

    #[test]
    fn test_all_sidecar_paths() {
        let base = Path::new("test.geo");
        let paths = all_sidecar_paths(base);
        assert_eq!(paths.len(), 3);
        assert!(paths.contains(&std::path::PathBuf::from("test.geo.cfg")));
        assert!(paths.contains(&std::path::PathBuf::from("test.geo.idx")));
        assert!(paths.contains(&std::path::PathBuf::from("test.geo.complexity")));
    }

    #[test]
    fn test_sidecar_paths_preserve_directory() {
        let base = Path::new("some/deep/path/to/file.geo");
        assert_eq!(
            geo_cfg_path(base),
            Path::new("some/deep/path/to/file.geo.cfg")
        );
        assert_eq!(
            geo_idx_path(base),
            Path::new("some/deep/path/to/file.geo.idx")
        );
        assert_eq!(
            geo_complexity_path(base),
            Path::new("some/deep/path/to/file.geo.complexity")
        );
    }
}
