package iace

import (
	"fmt"
	"testing"
)

func TestTagResolver_ResolveComponentTags_Roboterarm(t *testing.T) {
	tr := NewTagResolver()
	tags := tr.ResolveComponentTags([]string{"C001"}) // Roboterarm
	if len(tags) == 0 {
		t.Fatal("expected tags for C001 (Roboterarm), got none")
	}
	tagSet := toSet(tags)
	if !tagSet["moving_part"] {
		t.Error("expected 'moving_part' tag for Roboterarm")
	}
	if !tagSet["rotating_part"] {
		t.Error("expected 'rotating_part' tag for Roboterarm")
	}
}

func TestTagResolver_ResolveComponentTags_Schaltschrank(t *testing.T) {
	tr := NewTagResolver()
	tags := tr.ResolveComponentTags([]string{"C061"}) // Schaltschrank
	tagSet := toSet(tags)
	if !tagSet["high_voltage"] {
		t.Error("expected 'high_voltage' tag for Schaltschrank")
	}
	if !tagSet["electrical_part"] {
		t.Error("expected 'electrical_part' tag for Schaltschrank")
	}
}

func TestTagResolver_ResolveEnergyTags(t *testing.T) {
	tr := NewTagResolver()
	tags := tr.ResolveEnergyTags([]string{"EN01", "EN04"})
	tagSet := toSet(tags)
	if !tagSet["kinetic"] {
		t.Error("expected 'kinetic' tag for EN01")
	}
	if !tagSet["electrical_energy"] {
		t.Error("expected 'electrical_energy' tag for EN04")
	}
}

func TestTagResolver_ResolveTags_Merged(t *testing.T) {
	tr := NewTagResolver()
	tags := tr.ResolveTags(
		[]string{"C001"},      // Roboterarm → moving_part, rotating_part, high_force
		[]string{"EN01"},      // Kinetische Energie → kinetic, translational
		[]string{"custom_tag"},
	)
	tagSet := toSet(tags)
	if !tagSet["moving_part"] {
		t.Error("missing component tag 'moving_part'")
	}
	if !tagSet["kinetic"] {
		t.Error("missing energy tag 'kinetic'")
	}
	if !tagSet["custom_tag"] {
		t.Error("missing custom tag")
	}
}

func TestTagResolver_ResolveTags_NoDuplicates(t *testing.T) {
	tr := NewTagResolver()
	// C001 and C003 both have "moving_part"
	tags := tr.ResolveTags([]string{"C001", "C003"}, nil, nil)
	count := 0
	for _, t := range tags {
		if t == "moving_part" {
			count++
		}
	}
	if count != 1 {
		t.Errorf("expected 'moving_part' exactly once, got %d", count)
	}
}

func TestTagResolver_ResolveComponentTags_UnknownID(t *testing.T) {
	tr := NewTagResolver()
	tags := tr.ResolveComponentTags([]string{"UNKNOWN_ID"})
	if len(tags) != 0 {
		t.Errorf("expected no tags for unknown ID, got %v", tags)
	}
}

func TestTagResolver_ResolveComponentTags_Empty(t *testing.T) {
	tr := NewTagResolver()
	tags := tr.ResolveComponentTags(nil)
	if len(tags) != 0 {
		t.Errorf("expected no tags for nil input, got %v", tags)
	}
}

func TestTagResolver_FindHazardsByTags_Empty(t *testing.T) {
	tr := NewTagResolver()
	hazards := tr.FindHazardsByTags(nil)
	if len(hazards) != 0 {
		t.Errorf("expected no hazards for nil tags, got %d", len(hazards))
	}
}

func TestTagResolver_FindHazardsByTags_NonexistentTag(t *testing.T) {
	tr := NewTagResolver()
	hazards := tr.FindHazardsByTags([]string{"nonexistent_tag_xyz"})
	if len(hazards) != 0 {
		t.Errorf("expected no hazards for nonexistent tag, got %d", len(hazards))
	}
}

func TestTagResolver_FindMeasuresByTags_Empty(t *testing.T) {
	tr := NewTagResolver()
	measures := tr.FindMeasuresByTags(nil)
	if len(measures) != 0 {
		t.Errorf("expected no measures for nil tags, got %d", len(measures))
	}
}

func TestTagResolver_FindEvidenceByTags_DesignEvidence(t *testing.T) {
	tr := NewTagResolver()
	evidence := tr.FindEvidenceByTags([]string{"design_evidence"})
	if len(evidence) == 0 {
		t.Fatal("expected evidence for 'design_evidence' tag, got none")
	}
}

func TestTagResolver_FindEvidenceByTags_Empty(t *testing.T) {
	tr := NewTagResolver()
	evidence := tr.FindEvidenceByTags(nil)
	if len(evidence) != 0 {
		t.Errorf("expected no evidence for nil tags, got %d", len(evidence))
	}
}

func TestTagResolver_ResolveEnergyTags_AllSources(t *testing.T) {
	tr := NewTagResolver()
	// Test all 20 energy sources
	allIDs := make([]string, 20)
	for i := 0; i < 20; i++ {
		allIDs[i] = fmt.Sprintf("EN%02d", i+1)
	}
	tags := tr.ResolveEnergyTags(allIDs)
	if len(tags) < 10 {
		t.Errorf("expected at least 10 unique tags for all 20 energy sources, got %d", len(tags))
	}
}

func TestTagResolver_ResolveComponentTags_AllCategories(t *testing.T) {
	tr := NewTagResolver()
	// Test one component from each category
	sampleIDs := []string{
		"C001", // mechanical
		"C021", // structural
		"C031", // drive
		"C041", // hydraulic
		"C051", // pneumatic
		"C061", // electrical
		"C071", // control
		"C081", // sensor
		"C091", // actuator
		"C101", // safety
		"C111", // it_network
	}
	tags := tr.ResolveComponentTags(sampleIDs)
	if len(tags) < 15 {
		t.Errorf("expected at least 15 unique tags for 11 category samples, got %d", len(tags))
	}
}
