#![feature(concat_idents)]
pub mod graph_parser;
mod rust_bfs;

use graph_parser::*;

use hercules_rt::{runner, HerculesImmBox, HerculesImmBoxTo, HerculesMutBox};

use clap::Parser;

juno_build::juno!("bfs");

#[derive(Parser)]
#[clap(author, version, about, long_about = None)]
pub struct BFSInputs {
    pub input: String,
}

fn run_bfs(nodes: &[Node], source: u32, edges: &[u32]) -> Vec<i32> {
    let n = nodes.len() as u64;
    let m = edges.len() as u64;
    println!("Running with {} nodes and {} edges.", n, m);

    let nodes = HerculesImmBox::from(nodes);
    let edges = HerculesImmBox::from(edges);

    let mut runner = runner!(bfs);

    HerculesMutBox::from(async_std::task::block_on(async {
        runner.run(n, m, nodes.to(), source, edges.to()).await
    }))
    .as_slice()
    .to_vec()
}

pub fn bfs_harness(args: BFSInputs) {
    let BFSInputs { input } = args;

    let (nodes, source, edges) = parse_graph(input).unwrap();

    let costs_juno = run_bfs(&nodes, source, &edges);
    let costs_ref = rust_bfs::bfs(&nodes, source, &edges);

    assert_eq!(costs_juno, costs_ref);
}