package iace

import "testing"

// TestControlsLibrary_UniqueIDs verifies all control IDs are unique.
func TestControlsLibrary_UniqueIDs(t *testing.T) {
	seen := make(map[string]bool)
	for _, e := range GetControlsLibrary() {
		if e.ID == "" {
			t.Errorf("control has empty ID")
			continue
		}
		if seen[e.ID] {
			t.Errorf("duplicate control ID: %s", e.ID)
		}
		seen[e.ID] = true
	}
}

// TestProtectiveMeasures_HasExamples verifies measures have examples.
func TestProtectiveMeasures_HasExamples(t *testing.T) {
	withExamples := 0
	for _, e := range GetProtectiveMeasureLibrary() {
		if len(e.Examples) > 0 {
			withExamples++
		}
	}
	total := len(GetProtectiveMeasureLibrary())
	threshold := total * 80 / 100
	if withExamples < threshold {
		t.Errorf("only %d/%d measures have examples, want at least %d", withExamples, total, threshold)
	}
}

// TestProtectiveMeasures_ThreeReductionTypesPresent verifies all 3 types exist.
func TestProtectiveMeasures_ThreeReductionTypesPresent(t *testing.T) {
	types := make(map[string]int)
	for _, e := range GetProtectiveMeasureLibrary() {
		types[e.ReductionType]++
	}
	// Accept both naming variants
	designCount := types["design"]
	protectiveCount := types["protective"] + types["protection"]
	infoCount := types["information"]

	if designCount == 0 {
		t.Error("no measures with reduction type design")
	}
	if protectiveCount == 0 {
		t.Error("no measures with reduction type protective/protection")
	}
	if infoCount == 0 {
		t.Error("no measures with reduction type information")
	}
}

// TestProtectiveMeasures_TagFieldAccessible verifies the Tags field is accessible.
func TestProtectiveMeasures_TagFieldAccessible(t *testing.T) {
	measures := GetProtectiveMeasureLibrary()
	if len(measures) == 0 {
		t.Fatal("no measures returned")
	}
	// Tags field exists but may not be populated yet
	_ = measures[0].Tags
}

// TestProtectiveMeasures_HazardCategoryNotEmpty verifies HazardCategory is populated.
func TestProtectiveMeasures_HazardCategoryNotEmpty(t *testing.T) {
	for _, e := range GetProtectiveMeasureLibrary() {
		if e.HazardCategory == "" {
			t.Errorf("measure %s (%s): HazardCategory is empty", e.ID, e.Name)
		}
	}
}

// TestProtectiveMeasures_Count160 verifies at least 160 measures exist.
func TestProtectiveMeasures_Count160(t *testing.T) {
	entries := GetProtectiveMeasureLibrary()
	if len(entries) < 160 {
		t.Fatalf("got %d protective measures, want at least 160", len(entries))
	}
}

// TestProtectiveMeasures_SubTypesPresent verifies subtypes are used.
func TestProtectiveMeasures_SubTypesPresent(t *testing.T) {
	subtypes := make(map[string]int)
	for _, e := range GetProtectiveMeasureLibrary() {
		if e.SubType != "" {
			subtypes[e.SubType]++
		}
	}
	if len(subtypes) < 3 {
		t.Errorf("expected at least 3 different subtypes, got %d: %v", len(subtypes), subtypes)
	}
}
