package alerting

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestAddRule(t *testing.T) {
	am := NewAlertManager()
	rule := &AlertRule{
		ID:        "rule-1",
		Name:      "High Error Rate",
		Threshold: 0.1,
		Metric:    "error_rate",
		Level:     AlertError,
	}
	
	err := am.AddRule(rule)
	assert.NoError(t, err)
	
	rules := am.GetRules()
	assert.Equal(t, 1, len(rules))
}

func TestTriggerAlert(t *testing.T) {
	am := NewAlertManager()
	
	alert, err := am.TriggerAlert("Database Down", "PostgreSQL unavailable", AlertCritical)
	assert.NoError(t, err)
	assert.NotNil(t, alert)
	assert.Equal(t, AlertCritical, alert.Level)
}

func TestResolveAlert(t *testing.T) {
	am := NewAlertManager()
	
	alert, _ := am.TriggerAlert("Test Alert", "Test", AlertWarning)
	err := am.ResolveAlert(alert.ID)
	
	assert.NoError(t, err)
	assert.True(t, alert.Resolved)
}

func TestGetActiveAlerts(t *testing.T) {
	am := NewAlertManager()
	
	alert1, _ := am.TriggerAlert("Alert 1", "Test", AlertWarning)
	alert2, _ := am.TriggerAlert("Alert 2", "Test", AlertError)
	
	am.ResolveAlert(alert1.ID)
	
	active := am.GetActiveAlerts()
	assert.Equal(t, 1, len(active))
	assert.Equal(t, alert2.ID, active[0].ID)
}

func TestGetAlertsByLevel(t *testing.T) {
	am := NewAlertManager()
	
	am.TriggerAlert("Alert 1", "Test", AlertWarning)
	am.TriggerAlert("Alert 2", "Test", AlertError)
	am.TriggerAlert("Alert 3", "Test", AlertError)
	
	errors := am.GetAlertsByLevel(AlertError)
	assert.Equal(t, 2, len(errors))
}

func TestGetHistory(t *testing.T) {
	am := NewAlertManager()
	
	am.TriggerAlert("Alert 1", "Test", AlertWarning)
	am.TriggerAlert("Alert 2", "Test", AlertError)
	
	history := am.GetHistory()
	assert.Equal(t, 2, len(history))
}

func TestRemoveRule(t *testing.T) {
	am := NewAlertManager()
	
	rule := &AlertRule{
		ID:   "rule-1",
		Name: "Test Rule",
		Level: AlertWarning,
	}
	
	am.AddRule(rule)
	err := am.RemoveRule("rule-1")
	
	assert.NoError(t, err)
	rules := am.GetRules()
	assert.Equal(t, 0, len(rules))
}

func TestClear(t *testing.T) {
	am := NewAlertManager()
	
	am.TriggerAlert("Alert 1", "Test", AlertWarning)
	am.TriggerAlert("Alert 2", "Test", AlertError)
	
	am.Clear()
	
	assert.Equal(t, 0, am.GetAlertCount())
}

func TestEvaluateRule(t *testing.T) {
	am := NewAlertManager()
	
	rule := &AlertRule{
		ID:        "rule-1",
		Name:      "High Error Rate",
		Threshold: 0.1,
		Level:     AlertError,
	}
	
	am.AddRule(rule)
	
	alert, _ := am.EvaluateRule("rule-1", 0.15)
	assert.NotNil(t, alert)
}

func TestEvaluateRuleBelowThreshold(t *testing.T) {
	am := NewAlertManager()
	
	rule := &AlertRule{
		ID:        "rule-1",
		Name:      "High Error Rate",
		Threshold: 0.1,
		Level:     AlertError,
	}
	
	am.AddRule(rule)
	
	alert, _ := am.EvaluateRule("rule-1", 0.05)
	assert.Nil(t, alert)
}

func TestGetAlertCount(t *testing.T) {
	am := NewAlertManager()
	
	am.TriggerAlert("Alert 1", "Test", AlertWarning)
	am.TriggerAlert("Alert 2", "Test", AlertError)
	
	assert.Equal(t, 2, am.GetAlertCount())
}

func TestAddRuleError(t *testing.T) {
	am := NewAlertManager()
	
	rule := &AlertRule{
		Name: "No ID",
	}
	
	err := am.AddRule(rule)
	assert.Error(t, err)
}
