package collector

import (
	"os"
	"testing"
)

func TestParseBoard(t *testing.T) {
	type1 := mustReadFile(t, "testdata/dmidecode_type1.txt")
	type2 := mustReadFile(t, "testdata/dmidecode_type2.txt")

	board := parseBoard(type1, type2)

	if board.SerialNumber != "CAR315KA0803B90" {
		t.Errorf("serial_number: got %q, want %q", board.SerialNumber, "CAR315KA0803B90")
	}
	if board.Manufacturer == nil || *board.Manufacturer != "Inspur" {
		t.Errorf("manufacturer: got %v, want Inspur", board.Manufacturer)
	}
	if board.ProductName == nil || *board.ProductName != "NF5468M7" {
		t.Errorf("product_name: got %v, want NF5468M7", board.ProductName)
	}
	if board.PartNumber == nil || *board.PartNumber != "YZCA-02758-105" {
		t.Errorf("part_number: got %v, want YZCA-02758-105", board.PartNumber)
	}
	if board.UUID == nil || *board.UUID != "a1b2c3d4-e5f6-7890-abcd-ef1234567890" {
		t.Errorf("uuid: got %v, want a1b2c3d4-e5f6-7890-abcd-ef1234567890", board.UUID)
	}
}

func TestParseBoard_emptySerial(t *testing.T) {
	type1 := mustReadFile(t, "testdata/dmidecode_type1_empty_serial.txt")

	board := parseBoard(type1, "")

	if board.SerialNumber != "" {
		t.Errorf("expected empty serial for placeholder value, got %q", board.SerialNumber)
	}
	if board.Manufacturer != nil {
		t.Errorf("expected nil manufacturer for placeholder, got %q", *board.Manufacturer)
	}
	if board.UUID != nil {
		t.Errorf("expected nil UUID for 'Not Settable', got %q", *board.UUID)
	}
}

func TestParseBIOSFirmware(t *testing.T) {
	type0 := mustReadFile(t, "testdata/dmidecode_type0.txt")
	fw := parseBIOSFirmware(type0)

	if len(fw) != 1 {
		t.Fatalf("expected 1 firmware record, got %d", len(fw))
	}
	if fw[0].DeviceName != "BIOS" {
		t.Errorf("device_name: got %q, want BIOS", fw[0].DeviceName)
	}
	if fw[0].Version != "06.08.05" {
		t.Errorf("version: got %q, want 06.08.05", fw[0].Version)
	}
}

func TestParseBIOSFirmware_empty(t *testing.T) {
	fw := parseBIOSFirmware("")
	if len(fw) != 0 {
		t.Errorf("expected no firmware records for empty input, got %d", len(fw))
	}
}

func TestCleanDMIValue(t *testing.T) {
	tests := []struct {
		input string
		want  string
	}{
		{"CAR315KA0803B90", "CAR315KA0803B90"},
		{"To Be Filled By O.E.M.", ""},
		{"to be filled by o.e.m.", ""},
		{"Not Specified", ""},
		{"Not Settable", ""},
		{"Unknown", ""},
		{"N/A", ""},
		{"None", ""},
		{"NULL", ""},
		{"Default String", ""},
		{"  Inspur  ", "Inspur"},
		{"", ""},
		{"0", ""},
	}
	for _, tt := range tests {
		got := cleanDMIValue(tt.input)
		if got != tt.want {
			t.Errorf("cleanDMIValue(%q) = %q, want %q", tt.input, got, tt.want)
		}
	}
}

func TestParseDMIFields(t *testing.T) {
	type1 := mustReadFile(t, "testdata/dmidecode_type1.txt")
	fields := parseDMIFields(type1, "System Information")

	if fields["Manufacturer"] != "Inspur" {
		t.Errorf("Manufacturer: got %q", fields["Manufacturer"])
	}
	if fields["Serial Number"] != "CAR315KA0803B90" {
		t.Errorf("Serial Number: got %q", fields["Serial Number"])
	}
	// sub-list items must not be included
	if _, ok := fields["PCI is supported"]; ok {
		t.Error("sub-list item should not appear in fields")
	}
}

func mustReadFile(t *testing.T, path string) string {
	t.Helper()
	b, err := os.ReadFile(path)
	if err != nil {
		t.Fatalf("read fixture %s: %v", path, err)
	}
	return string(b)
}
