package iace

import "testing"

func TestDeltaMatch_NoChange(t *testing.T) {
	engine := NewPatternEngine()
	input := MatchInput{
		ComponentLibraryIDs: []string{"C001"},
		EnergySourceIDs:     []string{"EN01"},
	}
	result := engine.DeltaMatch(input, input)

	if len(result.AddedPatterns) != 0 {
		t.Errorf("expected 0 added patterns for no change, got %d", len(result.AddedPatterns))
	}
	if len(result.RemovedPatterns) != 0 {
		t.Errorf("expected 0 removed patterns for no change, got %d", len(result.RemovedPatterns))
	}
	if result.SummaryDE != "Keine Auswirkung — die vorgeschlagene Aenderung veraendert die Risikobeurteilung nicht." {
		t.Errorf("unexpected summary: %s", result.SummaryDE)
	}
}

func TestDeltaMatch_AddComponent(t *testing.T) {
	engine := NewPatternEngine()
	current := MatchInput{
		ComponentLibraryIDs: []string{"C001"},
		EnergySourceIDs:     []string{"EN01"},
	}
	proposed := MatchInput{
		ComponentLibraryIDs: []string{"C001", "C071"}, // Add SPS (programmable)
		EnergySourceIDs:     []string{"EN01"},
	}
	result := engine.DeltaMatch(current, proposed)

	if len(result.AddedPatterns) == 0 {
		t.Error("expected added patterns when adding SPS component")
	}
	t.Logf("Adding C071 (SPS): +%d patterns, +%d hazard cats, +%d measures",
		len(result.AddedPatterns), result.AddedHazardCount, result.AddedMeasureCount)
}

func TestDeltaMatch_RemoveComponent(t *testing.T) {
	engine := NewPatternEngine()
	current := MatchInput{
		ComponentLibraryIDs: []string{"C001", "C071"},
		EnergySourceIDs:     []string{"EN01"},
	}
	proposed := MatchInput{
		ComponentLibraryIDs: []string{"C001"}, // Remove SPS
		EnergySourceIDs:     []string{"EN01"},
	}
	result := engine.DeltaMatch(current, proposed)

	if len(result.RemovedPatterns) == 0 {
		t.Error("expected removed patterns when removing SPS component")
	}
	t.Logf("Removing C071: -%d patterns, -%d hazard cats",
		len(result.RemovedPatterns), result.RemovedHazardCount)
}

func TestDeltaMatch_AddState(t *testing.T) {
	engine := NewPatternEngine()
	current := MatchInput{
		ComponentLibraryIDs: []string{"C001", "C071"},
		EnergySourceIDs:     []string{"EN01"},
		LifecyclePhases:     []string{"normal_operation"},
		OperationalStates:   []string{"automatic_operation"},
		HumanRoles:          []string{"operator"},
	}
	proposed := MatchInput{
		ComponentLibraryIDs: []string{"C001", "C071"},
		EnergySourceIDs:     []string{"EN01"},
		LifecyclePhases:     []string{"normal_operation", "maintenance"},
		OperationalStates:   []string{"automatic_operation", "maintenance"},
		HumanRoles:          []string{"operator", "maintenance_tech"},
	}
	result := engine.DeltaMatch(current, proposed)

	t.Logf("Adding maintenance state+role: +%d patterns, +%d hazards, +%d measures",
		len(result.AddedPatterns), result.AddedHazardCount, result.AddedMeasureCount)

	// Adding maintenance should bring maintenance-specific patterns
	if len(result.AddedPatterns) == 0 {
		t.Error("expected added patterns when adding maintenance state")
	}
}

func TestDeltaMatch_AddRole(t *testing.T) {
	engine := NewPatternEngine()
	current := MatchInput{
		ComponentLibraryIDs: []string{"C001", "C071"},
		EnergySourceIDs:     []string{"EN01"},
		LifecyclePhases:     []string{"maintenance"},
		OperationalStates:   []string{"maintenance"},
		HumanRoles:          []string{"operator"}, // Only operator
	}
	proposed := MatchInput{
		ComponentLibraryIDs: []string{"C001", "C071"},
		EnergySourceIDs:     []string{"EN01"},
		LifecyclePhases:     []string{"maintenance"},
		OperationalStates:   []string{"maintenance"},
		HumanRoles:          []string{"operator", "maintenance_tech"}, // Add maintenance_tech
	}
	result := engine.DeltaMatch(current, proposed)

	t.Logf("Adding maintenance_tech role: +%d patterns", len(result.AddedPatterns))
	// maintenance_tech role should unlock maintenance-specific patterns
	if len(result.AddedPatterns) == 0 {
		t.Error("expected added patterns when adding maintenance_tech role")
	}
}

func TestDeltaMatch_SummaryNotEmpty(t *testing.T) {
	engine := NewPatternEngine()
	current := MatchInput{ComponentLibraryIDs: []string{"C001"}, EnergySourceIDs: []string{"EN01"}}
	proposed := MatchInput{ComponentLibraryIDs: []string{"C001", "C071"}, EnergySourceIDs: []string{"EN01"}}

	result := engine.DeltaMatch(current, proposed)
	if result.SummaryDE == "" {
		t.Error("expected non-empty summary")
	}
	t.Logf("Summary: %s", result.SummaryDE)
}

func TestDeltaMatch_Symmetric(t *testing.T) {
	engine := NewPatternEngine()
	a := MatchInput{ComponentLibraryIDs: []string{"C001"}, EnergySourceIDs: []string{"EN01"}}
	b := MatchInput{ComponentLibraryIDs: []string{"C001", "C071"}, EnergySourceIDs: []string{"EN01"}}

	forward := engine.DeltaMatch(a, b)
	backward := engine.DeltaMatch(b, a)

	if len(forward.AddedPatterns) != len(backward.RemovedPatterns) {
		t.Errorf("forward added (%d) should equal backward removed (%d)",
			len(forward.AddedPatterns), len(backward.RemovedPatterns))
	}
}
