use std::collections::HashSet;
use std::fs;
use std::path::{Path, PathBuf};

use anyhow::{bail, Context, Result};

/// Discover `.json` files in a directory, excluding specified crates.
///
/// Returns paths to all `.json` files in `json_dir` whose filename (without extension)
/// is not in `skip_crates`.
pub fn collect_crate_paths<P: AsRef<Path>>(
    json_dir: P,
    skip_crates: &[&str],
) -> Result<Vec<PathBuf>> {
    let json_dir = json_dir.as_ref();
    if !json_dir.is_dir() {
        bail!("{} is not a directory", json_dir.display());
    }

    let skip: HashSet<&str> = skip_crates.iter().copied().collect();
    let mut paths = Vec::new();

    for entry in fs::read_dir(json_dir)
        .with_context(|| format!("failed to read `{}`", json_dir.display()))?
    {
        let entry = entry?;
        let path = entry.path();
        if path.extension().and_then(|ext| ext.to_str()) != Some("json") {
            continue;
        }

        let stem = match path.file_stem().and_then(|s| s.to_str()) {
            Some(stem) => stem,
            None => continue,
        };

        if skip.contains(stem) {
            continue;
        }

        paths.push(path);
    }

    Ok(paths)
}
