// Package rules evaluates sentry threshold rules against a current snapshot
// and historical snapshots from the LRU cache.
package rules

import (
	"time"

	"github.com/nexuscrm/sentry/internal/types"
)

// HistoryFinder is the subset of the snapshot store that rules need.
// sentry/internal/store.LRU satisfies it.
type HistoryFinder interface {
	// FindClosest returns the snapshot in the given epoch whose SnapshotTs is
	// closest to target. ok=false if no same-epoch snapshot exists.
	FindClosest(target time.Time, epoch int64) (types.Snapshot, bool)
}

// Rule evaluates a current snapshot against historical snapshots and returns
// zero or more results. A rule that does not breach returns an empty slice;
// nil is also acceptable.
type Rule interface {
	ID() string
	Evaluate(current types.Snapshot, history HistoryFinder) []types.RuleResult
}

// Engine dispatches evaluation across a configured set of rules.
// Rules are evaluated in order; their results are concatenated.
type Engine struct {
	rules []Rule
}

// NewEngine constructs an Engine with the given rules.
// A nil or empty slice is valid — the engine simply produces no results.
func NewEngine(rules []Rule) *Engine {
	return &Engine{rules: rules}
}

// Evaluate runs every configured rule and returns all results.
// Order matches the rules slice passed to NewEngine.
func (e *Engine) Evaluate(current types.Snapshot, history HistoryFinder) []types.RuleResult {
	var results []types.RuleResult
	for _, r := range e.rules {
		results = append(results, r.Evaluate(current, history)...)
	}
	return results
}
