use crate::bvh::BVH;
use crate::mesh::TriangleMesh;
use super::oracle::BvhOracle;
use super::scheduler::CrawlerScheduler;
use super::{CrawlerConfig, SurfaceHit};

/// Run the crawler decompiler on CPU.
/// Uses the BVH for SDF queries. All crawlers run sequentially per step,
/// but SDF queries within each step can be parallelized.
pub fn run_cpu(
    mesh: &TriangleMesh,
    bvh: &BVH,
    config: CrawlerConfig,
) -> Vec<SurfaceHit> {
    let oracle = BvhOracle { mesh, bvh };
    let mut scheduler = CrawlerScheduler::new(mesh.bounds, config);
    scheduler.run(&oracle)
}

/// Run with the voxel oracle (faster per-query but lower precision).
/// Useful as intermediate step before GPU path.
pub fn run_cpu_voxel(
    mesh: &TriangleMesh,
    bvh: &BVH,
    config: CrawlerConfig,
    voxel_resolution: usize,
) -> Vec<SurfaceHit> {
    let oracle = super::oracle::VoxelOracle::from_mesh(mesh, bvh, voxel_resolution);
    let mut scheduler = CrawlerScheduler::new(mesh.bounds, config);
    scheduler.run(&oracle)
}
