1use crate::config::FuseRuleConfig;
2use crate::evaluator::{DataFusionEvaluator, RuleEvaluator};
3use crate::rule::Rule;
4use crate::RuleEngine;
5use anyhow::Result;
6use clap::Parser;
7
8#[derive(Parser)]
9pub struct ValidateArgs {
10 #[arg(short, long)]
12 config: String,
13
14 #[arg(short, long)]
16 predicate: Option<String>,
17}
18
19pub async fn validate_rule(config_path: &str, predicate: Option<&str>) -> Result<()> {
20 let config = FuseRuleConfig::from_file(config_path)?;
21
22 if let Some(pred) = predicate {
23 let evaluator = DataFusionEvaluator::new();
25 let schema = RuleEngine::from_config(config.clone())
26 .await
27 .map(|e| e.schema())?;
28
29 let test_rule = Rule {
30 id: "test".to_string(),
31 name: "Test Rule".to_string(),
32 predicate: pred.to_string(),
33 action: "logger".to_string(),
34 window_seconds: None,
35 version: 1,
36 enabled: true,
37 };
38
39 match evaluator.compile(test_rule, &schema) {
40 Ok(_) => {
41 println!("✅ Predicate is valid");
42 Ok(())
43 }
44 Err(e) => {
45 eprintln!("❌ Predicate validation failed: {}", e);
46 Err(e)
47 }
48 }
49 } else {
50 let evaluator = DataFusionEvaluator::new();
52 let engine = RuleEngine::from_config(config.clone()).await?;
53 let schema = engine.schema();
54
55 let mut all_valid = true;
56 for rule_cfg in &config.rules {
57 let rule = Rule {
58 id: rule_cfg.id.clone(),
59 name: rule_cfg.name.clone(),
60 predicate: rule_cfg.predicate.clone(),
61 action: rule_cfg.action.clone(),
62 window_seconds: rule_cfg.window_seconds,
63 version: rule_cfg.version,
64 enabled: rule_cfg.enabled,
65 };
66
67 match evaluator.compile(rule.clone(), &schema) {
68 Ok(compiled) => {
69 println!("✅ Rule '{}' ({}): Valid", rule.name, rule.id);
70 if compiled.has_aggregates {
71 println!(" └─ Contains aggregate functions");
72 }
73 }
74 Err(e) => {
75 eprintln!("❌ Rule '{}' ({}): Invalid - {}", rule.name, rule.id, e);
76 all_valid = false;
77 }
78 }
79 }
80
81 if all_valid {
82 println!("\n✅ All rules are valid");
83 Ok(())
84 } else {
85 anyhow::bail!("Some rules failed validation");
86 }
87 }
88}