67 lines
1.8 KiB
Go
67 lines
1.8 KiB
Go
package rules
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
)
|
|
|
|
// Engine evaluates rules against URL metadata
|
|
type Engine struct {
|
|
config *RuleConfig
|
|
logger *slog.Logger
|
|
}
|
|
|
|
// NewEngine creates a new rule engine with the given configuration
|
|
func NewEngine(config *RuleConfig) *Engine {
|
|
return &Engine{
|
|
config: config,
|
|
logger: slog.Default(),
|
|
}
|
|
}
|
|
|
|
// NewEngineWithLogger creates a new rule engine with the given configuration and logger
|
|
func NewEngineWithLogger(config *RuleConfig, logger *slog.Logger) *Engine {
|
|
return &Engine{
|
|
config: config,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// Evaluate evaluates rules against URL metadata and returns archivers
|
|
// Returns archivers from the first matching rule, or default archiver if no rules match
|
|
func (e *Engine) Evaluate(ctx context.Context, metadata *URLMetadata) ([]ArchiverConfig, error) {
|
|
if e.config == nil {
|
|
return nil, fmt.Errorf("rule engine: configuration is nil")
|
|
}
|
|
|
|
// Validate all rules
|
|
for i, rule := range e.config.Rules {
|
|
if err := rule.IsValid(); err != nil {
|
|
return nil, fmt.Errorf("rule engine: rule %d is invalid: %w", i, err)
|
|
}
|
|
}
|
|
|
|
// Evaluate rules in order
|
|
for i, rule := range e.config.Rules {
|
|
archivers, err := rule.Matches(ctx, metadata)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("rule engine: error evaluating rule %d: %w", i, err)
|
|
}
|
|
|
|
// If rule matched (returned archivers, including empty slice), use them and STOP
|
|
if archivers != nil {
|
|
e.logger.Info("Rule matched, stopping evaluation", "ruleIndex", i, "archiverCount", len(archivers))
|
|
return archivers, nil
|
|
}
|
|
}
|
|
|
|
// No rules matched, use default archivers
|
|
if len(e.config.DefaultArchivers) == 0 {
|
|
return nil, fmt.Errorf("rule engine: no rules matched and no default archivers configured")
|
|
}
|
|
|
|
e.logger.Info("No rules matched, using default archivers", "archivers", e.config.DefaultArchivers)
|
|
|
|
return e.config.DefaultArchivers, nil
|
|
}
|