//! Node management operations

use std::collections::HashMap;
use std::time::{Duration, SystemTime};

use super::NodeInfo;

/// Get list of currently known nodes
pub fn get_nodes(discovered_nodes: &HashMap<String, NodeInfo>) -> Vec<&NodeInfo> {
    discovered_nodes.values().collect()
}

/// Get a specific node by ID
///
/// # Arguments
///
/// * `discovered_nodes` - Map of discovered nodes
/// * `node_id` - Node identifier
pub fn get_node<'a>(discovered_nodes: &'a HashMap<String, NodeInfo>, node_id: &str) -> Option<&'a NodeInfo> {
    discovered_nodes.get(node_id)
}

/// Remove stale nodes that haven't sent heartbeats
///
/// # Arguments
///
/// * `discovered_nodes` - Mutable reference to discovered nodes map
/// * `timeout` - Maximum time since last heartbeat
///
/// # Returns
///
/// Number of nodes removed
pub fn cleanup_stale_nodes(discovered_nodes: &mut HashMap<String, NodeInfo>, timeout: Duration) -> usize {
    let now = SystemTime::now();
    let initial_count = discovered_nodes.len();

    discovered_nodes.retain(|_, node| now.duration_since(node.last_seen).map(|d| d < timeout).unwrap_or(false));

    initial_count - discovered_nodes.len()
}

/// Get node count
pub fn node_count(discovered_nodes: &HashMap<String, NodeInfo>) -> usize {
    discovered_nodes.len()
}

/// Get nodes by type
///
/// # Arguments
///
/// * `discovered_nodes` - Map of discovered nodes
/// * `node_type` - Type of nodes to filter
pub fn get_nodes_by_type<'a>(discovered_nodes: &'a HashMap<String, NodeInfo>, node_type: &str) -> Vec<&'a NodeInfo> {
    discovered_nodes
        .values()
        .filter(|node| node.node_type == node_type)
        .collect()
}

/// Clear all discovered nodes
pub fn clear(discovered_nodes: &mut HashMap<String, NodeInfo>) {
    discovered_nodes.clear();
}
