use std::path::{Path, PathBuf};
use std::sync::Arc;
use rsigma_runtime::{BuiltWebhook, MetricsHook, WebhooksFile, build_webhooks, load_webhooks_file};
pub fn load_and_build_webhooks(
paths: &[PathBuf],
metrics: Arc<dyn MetricsHook>,
) -> Result<Vec<BuiltWebhook>, String> {
let mut merged = WebhooksFile {
webhooks: Vec::new(),
};
for path in paths {
for file in expand(path)? {
let parsed = load_webhooks_file(&file).map_err(|e| e.to_string())?;
merged.webhooks.extend(parsed.webhooks);
}
}
let mut seen = std::collections::HashSet::new();
for webhook in &merged.webhooks {
if !seen.insert(webhook.id.clone()) {
return Err(format!("duplicate webhook id '{}'", webhook.id));
}
}
build_webhooks(merged, metrics).map_err(|e| e.to_string())
}
fn expand(path: &Path) -> Result<Vec<PathBuf>, String> {
if path.is_dir() {
let mut files: Vec<PathBuf> = std::fs::read_dir(path)
.map_err(|e| format!("failed to read webhook dir '{}': {e}", path.display()))?
.filter_map(|entry| entry.ok().map(|e| e.path()))
.filter(|p| {
p.extension()
.and_then(|s| s.to_str())
.is_some_and(|ext| ext == "yml" || ext == "yaml")
})
.collect();
files.sort();
Ok(files)
} else {
Ok(vec![path.to_path_buf()])
}
}