//! Pure project-selection logic — no I/O, no async, no side effects.
//!
//! All functions here are deterministic and depend only on their arguments.

/// Promote a project path to the front of the known-projects list.
///
/// Removes any existing occurrence of `path` and inserts it at position 0,
/// so the most-recently-opened project is always first.
pub fn promote_to_front(mut projects: Vec<String>, path: &str) -> Vec<String> {
    projects.retain(|p| p != path);
    projects.insert(0, path.to_string());
    projects
}

#[allow(dead_code)]
/// Extract the display name for a project from its filesystem path.
///
/// Returns the last non-empty path component, or `None` for root or empty input.
pub fn project_name_from_path(path: &str) -> Option<&str> {
    path.trim_end_matches('/')
        .rsplit('/')
        .find(|s| !s.is_empty())
}

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

    #[test]
    fn promote_to_front_inserts_new_path_at_position_zero() {
        let result = promote_to_front(vec!["/a".to_string(), "/b".to_string()], "/c");
        assert_eq!(result, vec!["/c", "/a", "/b"]);
    }

    #[test]
    fn promote_to_front_moves_existing_entry_to_front() {
        let result = promote_to_front(
            vec!["/a".to_string(), "/b".to_string(), "/c".to_string()],
            "/b",
        );
        assert_eq!(result, vec!["/b", "/a", "/c"]);
    }

    #[test]
    fn promote_to_front_is_idempotent_when_already_first() {
        let result = promote_to_front(vec!["/a".to_string(), "/b".to_string()], "/a");
        assert_eq!(result, vec!["/a", "/b"]);
    }

    #[test]
    fn promote_to_front_handles_empty_list() {
        let result = promote_to_front(vec![], "/new");
        assert_eq!(result, vec!["/new"]);
    }

    #[test]
    fn promote_to_front_deduplicates_single_entry() {
        let result = promote_to_front(vec!["/a".to_string()], "/a");
        assert_eq!(result, vec!["/a"]);
    }

    #[test]
    fn project_name_from_path_extracts_last_component() {
        assert_eq!(
            project_name_from_path("/home/user/myproject"),
            Some("myproject")
        );
    }

    #[test]
    fn project_name_from_path_handles_trailing_slash() {
        assert_eq!(
            project_name_from_path("/home/user/myproject/"),
            Some("myproject")
        );
    }

    #[test]
    fn project_name_from_path_returns_none_for_root() {
        assert_eq!(project_name_from_path("/"), None);
    }

    #[test]
    fn project_name_from_path_returns_none_for_empty() {
        assert_eq!(project_name_from_path(""), None);
    }

    #[test]
    fn project_name_from_path_handles_single_component() {
        assert_eq!(project_name_from_path("myproject"), Some("myproject"));
    }

    #[test]
    fn project_name_from_path_handles_deep_path() {
        assert_eq!(
            project_name_from_path("/a/b/c/d/project-name"),
            Some("project-name")
        );
    }
}
