///|
pub(all) struct RuleIssue {
  rule_id : String
  message : String
} derive(Debug, Eq)

///|
pub fn validate_rule(rule : Rule) -> Array[RuleIssue] {
  let issues = []
  if rule.id.trim().is_empty() {
    issues.push({ rule_id: rule.id, message: "rule id is empty" })
  }
  if rule.pattern.trim().is_empty() {
    issues.push({ rule_id: rule.id, message: "pattern is empty" })
  } else {
    ignore(@regexp.compile(rule.pattern)) catch {
      err => issues.push({ rule_id: rule.id, message: "invalid regex: \{err}" })
    }
  }
  if rule.confidence < 0 || rule.confidence > 100 {
    issues.push({ rule_id: rule.id, message: "confidence must be 0..100" })
  }
  if rule.placeholder.trim().is_empty() {
    issues.push({ rule_id: rule.id, message: "placeholder is empty" })
  }
  issues
}

///|
pub fn validate_rules(rules : Array[Rule]) -> Array[RuleIssue] {
  let issues = []
  let seen : Map[String, Unit] = Map([])
  for rule in rules {
    if seen.contains(rule.id) {
      issues.push({ rule_id: rule.id, message: "duplicate rule id" })
    }
    seen[rule.id] = ()
    issues.append(validate_rule(rule))
  }
  issues
}