package iace

import (
	"strings"
	"testing"
)

// TestManufacturerLibrary_HasTopManufacturers checks the curated baseline
// (~50 entries across major mechanical/plant-engineering segments). The
// expected manufacturers below are the ones that would be unsurprising to
// find in any industrial risk-assessment context.
func TestManufacturerLibrary_HasTopManufacturers(t *testing.T) {
	required := []string{
		"FANUC", "KUKA", "ABB Robotics", "Yaskawa Motoman", "Universal Robots",
		"DMG MORI", "Mazak", "TRUMPF", "Heidenhain",
		"Festo", "SMC", "Bosch Rexroth",
		"PILZ", "SICK", "Schmersal", "Euchner",
		"Siemens", "Beckhoff", "Rockwell Automation",
		"Schuler", "Arburg", "KraussMaffei",
	}
	have := map[string]bool{}
	for _, mf := range GetManufacturerSafetyFeatures() {
		have[mf.Manufacturer] = true
	}
	for _, want := range required {
		if !have[want] {
			t.Errorf("manufacturer library missing %q", want)
		}
	}
}

// TestManufacturerLibrary_AllHaveNorms pins that every entry carries at
// least one EN/ISO/IEC norm reference. A manufacturer entry without norm
// anchor is just hearsay; with it, the operator has something verifiable.
func TestManufacturerLibrary_AllHaveNorms(t *testing.T) {
	for _, mf := range GetManufacturerSafetyFeatures() {
		if len(mf.NormReferences) == 0 {
			t.Errorf("manufacturer %q (%s) missing NormReferences", mf.Manufacturer, mf.FeatureName)
		}
		if len(mf.Clarifications) == 0 {
			t.Errorf("manufacturer %q (%s) missing Clarifications", mf.Manufacturer, mf.FeatureName)
		}
	}
}

// TestLookupManufacturerFeaturesInText_FindsFANUC reproduces the GT-Bremse
// scenario: a narrative mentioning "Robodrill" must surface the FANUC DCS
// entry — that's how the operator gets the right clarification question
// without us inventing commentary.
func TestLookupManufacturerFeaturesInText_FindsFANUC(t *testing.T) {
	narrative := "Roboterzelle mit Fanuc Robodrill Werkzeugmaschine und KUKA-Roboter."
	hits := LookupManufacturerFeaturesInText(narrative)
	manufacturers := map[string]bool{}
	for _, h := range hits {
		manufacturers[h.Manufacturer] = true
	}
	if !manufacturers["FANUC"] {
		t.Errorf("expected FANUC hit for narrative %q, got %v", narrative, manufacturers)
	}
	if !manufacturers["KUKA"] {
		t.Errorf("expected KUKA hit for narrative %q, got %v", narrative, manufacturers)
	}
}

// TestLookupManufacturerFeaturesInText_HandlesUmlauts pins case + umlaut
// robustness — "Stäubli" must match alias "staeubli".
func TestLookupManufacturerFeaturesInText_HandlesUmlauts(t *testing.T) {
	hits := LookupManufacturerFeaturesInText("Stäubli TX2 Roboter und Schmersal Türverriegelung")
	manufacturers := map[string]bool{}
	for _, h := range hits {
		manufacturers[h.Manufacturer] = true
	}
	if !manufacturers["Stäubli Robotics"] {
		t.Errorf("expected Staeubli hit, got %v", manufacturers)
	}
	if !manufacturers["Schmersal"] {
		t.Errorf("expected Schmersal hit, got %v", manufacturers)
	}
}

// TestLookupManufacturerFeaturesInText_EmptyText handles missing narrative
// gracefully — must not crash and must return nil/empty.
func TestLookupManufacturerFeaturesInText_EmptyText(t *testing.T) {
	if hits := LookupManufacturerFeaturesInText(""); len(hits) > 0 {
		t.Errorf("expected no hits for empty narrative, got %d", len(hits))
	}
}

// TestManufacturerLibrary_Has50OrMore checks the target count of the
// curated set so a future regression that deletes many entries fails CI.
func TestManufacturerLibrary_Has50OrMore(t *testing.T) {
	got := len(GetManufacturerSafetyFeatures())
	if got < 50 {
		// Allow small undercount but keep the floor strict
		t.Errorf("manufacturer library has %d entries, expected >= 50", got)
	}
}

// TestNormalizeForMatch pins the umlaut/case folding behavior.
func TestNormalizeForMatch(t *testing.T) {
	cases := []struct{ in, want string }{
		{"Stäubli", "staeubli"},
		{"FANUC", "fanuc"},
		{"Schäffer", "schaeffer"},
		{"Mößbauer", "moessbauer"},
	}
	for _, c := range cases {
		if got := normalizeForMatch(c.in); got != c.want {
			t.Errorf("normalizeForMatch(%q) = %q, want %q", c.in, got, c.want)
		}
	}
}

// TestManufacturerLibrary_NormReferencesAreRealNorms scans for the standard
// norm prefixes so a future "we just put a placeholder" regression fails.
func TestManufacturerLibrary_NormReferencesAreRealNorms(t *testing.T) {
	for _, mf := range GetManufacturerSafetyFeatures() {
		ok := false
		for _, n := range mf.NormReferences {
			for _, prefix := range []string{"EN ", "IEC ", "ISO ", "DIN ", "EN ISO", "DIN EN", "VDE", "TRBS", "TRGS"} {
				if strings.HasPrefix(n, prefix) {
					ok = true
					break
				}
			}
			if ok {
				break
			}
		}
		if !ok {
			t.Errorf("manufacturer %q has no recognized norm prefix in %v", mf.Manufacturer, mf.NormReferences)
		}
	}
}
