#[cfg(not(feature = "datasets"))]
fn main() {}

#[cfg(feature = "datasets")]
fn main() {
    use std::collections::VecDeque;

    use spokes::{
        Network,
        algorithms::{Distance, dijkstra_shortest_path},
        datasets::knuth_miles,
    };

    let mut network: Network<u16, spokes::datasets::KnuthMilesNodeAttributes, u16> = knuth_miles();

    let start_id = network
        .iter_nodes()
        .find_map(|(&id, node)| {
            if node.name == "San Jose, CA" {
                Some(id)
            } else {
                None
            }
        })
        .expect("Should exist");

    let end_id = network
        .iter_nodes()
        .find_map(|(&id, node)| {
            if node.name == "Rochester, NY" {
                Some(id)
            } else {
                None
            }
        })
        .expect("Should exist");

    // Remove arcs longer than 500 mi.
    let arcs_to_remove: Vec<(u16, u16)> = network
        .arc_iter()
        .filter_map(|arc| {
            if arc.attributes > 500 {
                Some((arc.tail, arc.head))
            } else {
                None
            }
        })
        .collect();

    network.remove_arcs(arcs_to_remove.iter().map(|(a, b)| (a, b)));

    // Run Dijkstra's algorithm on the resulting network
    let shortest_distance_network: Network<u16, Distance<u16>, ()> =
        dijkstra_shortest_path(&network, start_id);

    let dist = shortest_distance_network
        .node(&end_id)
        .expect("Should exist");

    println!("Distance from San Jose, CA to Rochester, NY = {dist}");

    let mut stack = VecDeque::new();
    stack.push_front(end_id);
    let mut cur = end_id;

    while let Some(next) = shortest_distance_network.forward_arcs(&cur.clone()).next() {
        stack.push_front(next.head);
        cur = next.head;
    }

    let path: Vec<String> = stack
        .into_iter()
        .map(|i| network.node(&i).expect("Node should exist").name.clone())
        .collect();

    println!("Path = {path:#?}");
}
