package iace

import "testing"

// firedSet runs the engine for the given custom tags and returns the set of
// fired pattern IDs.
func firedSet(customTags []string) map[string]bool {
	engine := NewPatternEngine()
	out := engine.Match(MatchInput{CustomTags: customTags})
	fired := make(map[string]bool, len(out.MatchedPatterns))
	for _, m := range out.MatchedPatterns {
		fired[m.PatternID] = true
	}
	return fired
}

// A warewashing narrative emits these capability + functional tags.
var warewashingTags = []string{
	"dom_warewashing", "steam_emission", "hot_water", "high_temperature",
	"corrosive_chemical", "access_door", "rotating_part",
}

func TestWarewashing_PatternsFireForDishwasher(t *testing.T) {
	fired := firedSet(warewashingTags)
	want := []string{"HP2200", "HP2201", "HP2202", "HP2203", "HP2204", "HP2205", "HP2206"}
	for _, id := range want {
		if !fired[id] {
			t.Errorf("expected warewashing pattern %s to fire for a dishwasher, but it did not", id)
		}
	}
}

func TestWarewashing_PatternsDoNotLeakIntoOtherMachines(t *testing.T) {
	// A machine with thermal + electrical + chemical capability but NOT a
	// dishwasher must never produce warewashing hazards (dom_warewashing gate).
	fired := firedSet([]string{"high_temperature", "electrical_part", "chemical_risk", "rotating_part", "moving_part"})
	for _, id := range []string{"HP2200", "HP2201", "HP2202", "HP2203", "HP2204", "HP2205", "HP2206"} {
		if fired[id] {
			t.Errorf("warewashing pattern %s leaked into a non-dishwasher machine", id)
		}
	}
}

func TestWarewashing_WeldingAndGlueDoNotLeakIntoDishwasher(t *testing.T) {
	// The gate-term additions must stop the welding/flame/glue burn patterns
	// from firing for a dishwasher (they previously leaked via high_temperature
	// / electrical_part). dom_welding/dom_flame/dom_glue are absent here.
	fired := firedSet(warewashingTags)
	leak := map[string]string{
		"HP530": "Lichtbogen-Verbrennung (Schweissen)",
		"HP532": "Schweissrauch",
		"HP533": "Brand durch Schweissfunken (Schweissen)",
	}
	for id, name := range leak {
		if fired[id] {
			t.Errorf("cross-domain pattern %s (%s) leaked into a dishwasher", id, name)
		}
	}
}

func TestWarewashing_MeasureIDsExist(t *testing.T) {
	lib := GetProtectiveMeasureLibrary()
	have := make(map[string]bool, len(lib))
	for _, m := range lib {
		have[m.ID] = true
	}
	for _, p := range GetWarewashingPatterns() {
		for _, mid := range p.SuggestedMeasureIDs {
			if !have[mid] {
				t.Errorf("pattern %s references measure %s which is not in the library", p.ID, mid)
			}
		}
	}
}

func TestWarewashing_NarrativeEmitsTags(t *testing.T) {
	// Closes the loop: a realistic dishwasher description must emit the tags
	// the warewashing patterns gate on (otherwise the patterns are dead).
	narrative := "Gewerbliche Untertisch-Geschirrspuelmaschine mit Heisswasser-Boiler " +
		"und Nachspuelung ca. 85 Grad C, Spuelpumpe mit rotierenden Spuelfeldern, " +
		"Dampf-/Wrasenabgabe beim Oeffnen, Reiniger und Klarspueler ueber Dosiergeraet, " +
		"Tuer mit Sicherheitsschalter, Eingreifen in die Spuelkammer."
	res := ParseNarrative(narrative, "Gewerbliche Geschirrspuelmaschine")
	got := make(map[string]bool, len(res.CustomTags))
	for _, tag := range res.CustomTags {
		got[tag] = true
	}
	for _, want := range []string{"dom_warewashing", "steam_emission", "hot_water", "corrosive_chemical", "access_door", "rotating_part"} {
		if !got[want] {
			t.Errorf("narrative did not emit expected tag %q (got %v)", want, res.CustomTags)
		}
	}
	// And it must NOT emit any welding/flame/glue domain that would re-open leaks.
	for _, bad := range []string{"dom_welding", "dom_flame", "dom_glue"} {
		if got[bad] {
			t.Errorf("dishwasher narrative unexpectedly emitted cross-domain tag %q", bad)
		}
	}
}

func TestWarewashing_NewMeasuresPresent(t *testing.T) {
	lib := GetProtectiveMeasureLibrary()
	have := make(map[string]bool, len(lib))
	for _, m := range lib {
		have[m.ID] = true
	}
	for _, mid := range []string{"M2200", "M2201", "M2202", "M2203", "M2204", "M2205", "M2206", "M2207", "M2208"} {
		if !have[mid] {
			t.Errorf("expected warewashing measure %s to be registered in the library", mid)
		}
	}
}
