package handlers

import "testing"

// TestAcceptableMeasureCategories pins the set-based category acceptance map.
// Each pattern category accepts not just its own measure category but a
// curated set of semantically related ones — a safety_function_failure
// pattern is sensibly mitigated by software_control measures (watchdogs,
// plausibility checks), not just by the near-empty safety_function category.
func TestAcceptableMeasureCategories(t *testing.T) {
	cases := []struct {
		patternCat string
		mustAccept []string // measure categories that MUST be accepted
		mustReject []string // measure categories that MUST be rejected
	}{
		// mechanical hazards: own + general only
		{"mechanical_hazard", []string{"mechanical", "general"}, []string{"thermal", "electrical"}},
		// electrical hazards: own + general only
		{"electrical_hazard", []string{"electrical", "general"}, []string{"thermal", "mechanical"}},
		// safety-function failures accept watchdogs (software_control)
		{"safety_function_failure", []string{"safety_function", "software_control", "general"}, []string{"mechanical", "thermal"}},
		// EMC accepts electrical + software (shielding + filter logic both apply)
		{"emc_hazard", []string{"electrical", "software_control", "general"}, []string{"mechanical"}},
		// AI failures accept ai_specific + software_control
		{"false_classification", []string{"ai_specific", "software_control", "general"}, []string{"mechanical", "electrical"}},
		// Fire/explosion accepts thermal + material_environmental
		{"fire_explosion", []string{"thermal", "material_environmental", "general"}, []string{"mechanical", "electrical"}},
		// Unknown pattern category: only general
		{"unknown_made_up_cat", []string{"general"}, []string{"mechanical", "electrical"}},
	}
	for _, c := range cases {
		accepted := acceptableMeasureCategories(c.patternCat)
		for _, mc := range c.mustAccept {
			if !isCategoryCompatible(mc, accepted) {
				t.Errorf("patternCat=%q must accept measureCat=%q but rejected (set=%v)",
					c.patternCat, mc, accepted)
			}
		}
		for _, mc := range c.mustReject {
			if isCategoryCompatible(mc, accepted) {
				t.Errorf("patternCat=%q must reject measureCat=%q but accepted (set=%v)",
					c.patternCat, mc, accepted)
			}
		}
	}
}

// TestIsCategoryCompatible_EmptyMeasureCat pins that legacy measures with
// no HazardCategory set are always allowed — they would otherwise silently
// disappear during the re-init, since the audit found ~80 such entries in
// older library files.
func TestIsCategoryCompatible_EmptyMeasureCat(t *testing.T) {
	accepted := acceptableMeasureCategories("mechanical_hazard")
	if !isCategoryCompatible("", accepted) {
		t.Error("empty measure category must be accepted (legacy entries)")
	}
}
