package rules // RuleAware defines the interface for entities that can use rules type RuleAware interface { // GetRuleManager returns the rule manager instance GetRuleManager() *RuleManager // GetZoneID returns the zone ID for zone-specific rules (0 for global) GetZoneID() int32 } // RuleProvider defines the interface for providing rule access type RuleProvider interface { // GetRule gets a rule by category and type, with optional zone override GetRule(category RuleCategory, ruleType RuleType, zoneID int32) *Rule // GetRuleByName gets a rule by category and type names, with optional zone override GetRuleByName(categoryName string, typeName string, zoneID int32) *Rule // GetGlobalRule gets a rule from the global rule set GetGlobalRule(category RuleCategory, ruleType RuleType) *Rule // GetZoneRule gets a zone-specific rule, falling back to global GetZoneRule(zoneID int32, category RuleCategory, ruleType RuleType) *Rule } // DatabaseInterface defines the interface for rule database operations type DatabaseInterface interface { // LoadRuleSets loads all rule sets from database LoadRuleSets(ruleManager *RuleManager, reload bool) error // LoadGlobalRuleSet loads the global rule set LoadGlobalRuleSet(ruleManager *RuleManager) error // SaveRuleSet saves a rule set to database SaveRuleSet(ruleSet *RuleSet) error // DeleteRuleSet deletes a rule set from database DeleteRuleSet(ruleSetID int32) error // SetDefaultRuleSet sets the default rule set SetDefaultRuleSet(ruleSetID int32) error // GetDefaultRuleSetID gets the default rule set ID GetDefaultRuleSetID() (int32, error) // GetRuleSetList gets all rule sets GetRuleSetList() ([]RuleSetInfo, error) // ValidateDatabase validates required tables exist ValidateDatabase() error // CreateRulesTables creates the necessary database tables CreateRulesTables() error } // ConfigurationProvider defines the interface for configuration-based rule access type ConfigurationProvider interface { // GetConfigValue gets a configuration value by key GetConfigValue(key string) (string, bool) // SetConfigValue sets a configuration value SetConfigValue(key string, value string) error // GetConfigValueInt gets a configuration value as integer GetConfigValueInt(key string, defaultValue int32) int32 // GetConfigValueFloat gets a configuration value as float GetConfigValueFloat(key string, defaultValue float64) float64 // GetConfigValueBool gets a configuration value as boolean GetConfigValueBool(key string, defaultValue bool) bool } // RuleValidator defines the interface for rule validation type RuleValidator interface { // ValidateRule validates a rule's value ValidateRule(category RuleCategory, ruleType RuleType, value string) error // ValidateRuleSet validates an entire rule set ValidateRuleSet(ruleSet *RuleSet) []error // GetValidationRules gets validation rules for a category GetValidationRules(category RuleCategory) map[RuleType]ValidationRule } // ValidationRule defines validation criteria for a rule type ValidationRule struct { Required bool // Whether the rule is required MinValue any // Minimum allowed value (for numeric types) MaxValue any // Maximum allowed value (for numeric types) ValidValues []string // List of valid string values Pattern string // Regex pattern for validation Description string // Description of the rule } // RuleEventHandler defines the interface for rule change events type RuleEventHandler interface { // OnRuleChanged is called when a rule value changes OnRuleChanged(category RuleCategory, ruleType RuleType, oldValue string, newValue string) // OnRuleSetChanged is called when a rule set is modified OnRuleSetChanged(ruleSetID int32, action string) // OnGlobalRuleSetChanged is called when the global rule set changes OnGlobalRuleSetChanged(oldRuleSetID int32, newRuleSetID int32) } // RuleCache defines the interface for rule caching type RuleCache interface { // GetCachedRule gets a cached rule GetCachedRule(key string) (*Rule, bool) // CacheRule caches a rule CacheRule(key string, rule *Rule, ttl int64) // InvalidateCache invalidates cached rules InvalidateCache(pattern string) // ClearCache clears all cached rules ClearCache() // GetCacheStats gets cache statistics GetCacheStats() CacheStats } // CacheStats contains cache performance statistics type CacheStats struct { Hits int64 // Number of cache hits Misses int64 // Number of cache misses Entries int64 // Number of cached entries Memory int64 // Memory usage in bytes HitRatio float64 // Cache hit ratio LastCleared int64 // Timestamp of last cache clear } // RuleManagerAdapter provides a simplified interface to the rule manager type RuleManagerAdapter struct { ruleManager *RuleManager zoneID int32 } // NewRuleManagerAdapter creates a new rule manager adapter func NewRuleManagerAdapter(ruleManager *RuleManager, zoneID int32) *RuleManagerAdapter { return &RuleManagerAdapter{ ruleManager: ruleManager, zoneID: zoneID, } } // GetRule gets a rule using the adapter's zone ID func (rma *RuleManagerAdapter) GetRule(category RuleCategory, ruleType RuleType) *Rule { if rma.zoneID != 0 { return rma.ruleManager.GetZoneRule(rma.zoneID, category, ruleType) } return rma.ruleManager.GetGlobalRule(category, ruleType) } // GetRuleByName gets a rule by name using the adapter's zone ID func (rma *RuleManagerAdapter) GetRuleByName(categoryName string, typeName string) *Rule { rule := rma.ruleManager.GetGlobalRuleByName(categoryName, typeName) // If we have a zone ID, check for zone-specific override if rma.zoneID != 0 && rule != nil { zoneRule := rma.ruleManager.GetZoneRule(rma.zoneID, rule.GetCategory(), rule.GetType()) if zoneRule != nil { return zoneRule } } return rule } // GetInt32 gets a rule value as int32 func (rma *RuleManagerAdapter) GetInt32(category RuleCategory, ruleType RuleType) int32 { rule := rma.GetRule(category, ruleType) if rule != nil { return rule.GetInt32() } return 0 } // GetFloat64 gets a rule value as float64 func (rma *RuleManagerAdapter) GetFloat64(category RuleCategory, ruleType RuleType) float64 { rule := rma.GetRule(category, ruleType) if rule != nil { return rule.GetFloat64() } return 0.0 } // GetBool gets a rule value as bool func (rma *RuleManagerAdapter) GetBool(category RuleCategory, ruleType RuleType) bool { rule := rma.GetRule(category, ruleType) if rule != nil { return rule.GetBool() } return false } // GetString gets a rule value as string func (rma *RuleManagerAdapter) GetString(category RuleCategory, ruleType RuleType) string { rule := rma.GetRule(category, ruleType) if rule != nil { return rule.GetString() } return "" } // SetZoneID sets the zone ID for the adapter func (rma *RuleManagerAdapter) SetZoneID(zoneID int32) { rma.zoneID = zoneID } // GetZoneID gets the current zone ID func (rma *RuleManagerAdapter) GetZoneID() int32 { return rma.zoneID } // RuleServiceConfig contains configuration for rule services type RuleServiceConfig struct { DatabaseEnabled bool // Whether to use database storage CacheEnabled bool // Whether to enable rule caching CacheTTL int64 // Cache TTL in seconds MaxCacheSize int64 // Maximum cache size in bytes EventHandlers []RuleEventHandler // Event handlers to register Validators []RuleValidator // Validators to register } // RuleService provides high-level rule management functionality type RuleService struct { ruleManager *RuleManager database DatabaseInterface cache RuleCache eventHandlers []RuleEventHandler validators []RuleValidator config RuleServiceConfig } // NewRuleService creates a new rule service func NewRuleService(config RuleServiceConfig) *RuleService { return &RuleService{ ruleManager: NewRuleManager(), eventHandlers: config.EventHandlers, validators: config.Validators, config: config, } } // Initialize initializes the rule service func (rs *RuleService) Initialize() error { // Load rules from database if enabled if rs.config.DatabaseEnabled && rs.database != nil { err := rs.database.LoadRuleSets(rs.ruleManager, false) if err != nil { return err } } return nil } // GetRuleManager returns the underlying rule manager func (rs *RuleService) GetRuleManager() *RuleManager { return rs.ruleManager } // GetAdapter returns a rule manager adapter for a specific zone func (rs *RuleService) GetAdapter(zoneID int32) *RuleManagerAdapter { return NewRuleManagerAdapter(rs.ruleManager, zoneID) } // SetDatabase sets the database service func (rs *RuleService) SetDatabase(db DatabaseInterface) { rs.database = db } // SetCache sets the cache service func (rs *RuleService) SetCache(cache RuleCache) { rs.cache = cache } // AddEventHandler adds an event handler func (rs *RuleService) AddEventHandler(handler RuleEventHandler) { rs.eventHandlers = append(rs.eventHandlers, handler) } // AddValidator adds a validator func (rs *RuleService) AddValidator(validator RuleValidator) { rs.validators = append(rs.validators, validator) } // Shutdown shuts down the rule service func (rs *RuleService) Shutdown() error { // Clear cache if enabled if rs.cache != nil { rs.cache.ClearCache() } return nil }