package redfishprofile

import (
	"archive/zip"
	"encoding/json"
	"os"
	"path/filepath"
	"testing"
)

func TestCollectSignalsFromTree_InspurGroupOEMPlatformsSelectsMatchedMode(t *testing.T) {
	tree := map[string]interface{}{
		"/redfish/v1": map[string]interface{}{
			"@odata.id": "/redfish/v1",
		},
		"/redfish/v1/Systems": map[string]interface{}{
			"Members": []interface{}{
				map[string]interface{}{"@odata.id": "/redfish/v1/Systems/1"},
			},
		},
		"/redfish/v1/Systems/1": map[string]interface{}{
			"@odata.id": "/redfish/v1/Systems/1",
			"Oem": map[string]interface{}{
				"Public": map[string]interface{}{
					"USB": map[string]interface{}{
						"@odata.id": "/redfish/v1/Systems/1/Oem/Public/GetServerAllUSBStatus",
					},
				},
			},
			"NetworkInterfaces": map[string]interface{}{
				"@odata.id": "/redfish/v1/Systems/1/NetworkInterfaces",
			},
		},
		"/redfish/v1/Systems/1/NetworkInterfaces": map[string]interface{}{
			"Members": []interface{}{
				map[string]interface{}{"@odata.id": "/redfish/v1/Systems/1/NetworkInterfaces/outboardPCIeCard0"},
				map[string]interface{}{"@odata.id": "/redfish/v1/Systems/1/NetworkInterfaces/outboardPCIeCard1"},
			},
		},
		"/redfish/v1/Chassis": map[string]interface{}{
			"Members": []interface{}{
				map[string]interface{}{"@odata.id": "/redfish/v1/Chassis/1"},
			},
		},
		"/redfish/v1/Chassis/1": map[string]interface{}{
			"@odata.id": "/redfish/v1/Chassis/1",
			"Actions": map[string]interface{}{
				"Oem": map[string]interface{}{
					"Public": map[string]interface{}{
						"NvGpuPowerLimitWatts": map[string]interface{}{
							"target": "/redfish/v1/Chassis/1/GPU/EnvironmentMetrcs",
						},
					},
				},
			},
			"Drives": map[string]interface{}{
				"@odata.id": "/redfish/v1/Chassis/1/Drives",
			},
			"NetworkAdapters": map[string]interface{}{
				"@odata.id": "/redfish/v1/Chassis/1/NetworkAdapters",
			},
		},
		"/redfish/v1/Chassis/1/Drives": map[string]interface{}{
			"Members": []interface{}{
				map[string]interface{}{"@odata.id": "/redfish/v1/Chassis/1/Drives/OB01"},
				map[string]interface{}{"@odata.id": "/redfish/v1/Chassis/1/Drives/FP00HDD00"},
			},
		},
		"/redfish/v1/Chassis/1/NetworkAdapters": map[string]interface{}{
			"Members": []interface{}{
				map[string]interface{}{"@odata.id": "/redfish/v1/Chassis/1/NetworkAdapters/outboardPCIeCard0"},
				map[string]interface{}{"@odata.id": "/redfish/v1/Chassis/1/NetworkAdapters/outboardPCIeCard1"},
			},
		},
		"/redfish/v1/Chassis/1/Assembly": map[string]interface{}{
			"Assemblies": []interface{}{
				map[string]interface{}{
					"Oem": map[string]interface{}{
						"COMMONb": map[string]interface{}{
							"COMMONbAssembly": map[string]interface{}{
								"@odata.type": "#COMMONbAssembly.v1_0_0.COMMONbAssembly",
							},
						},
					},
				},
			},
		},
		"/redfish/v1/Managers": map[string]interface{}{
			"Members": []interface{}{
				map[string]interface{}{"@odata.id": "/redfish/v1/Managers/1"},
			},
		},
		"/redfish/v1/Managers/1": map[string]interface{}{
			"Actions": map[string]interface{}{
				"Oem": map[string]interface{}{
					"#PublicManager.ExportConfFile": map[string]interface{}{
						"target": "/redfish/v1/Managers/1/Actions/Oem/Public/ExportConfFile",
					},
				},
			},
		},
		"/redfish/v1/UpdateService/FirmwareInventory": map[string]interface{}{
			"Members": []interface{}{
				map[string]interface{}{"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/Front_HDD_CPLD0"},
				map[string]interface{}{"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/SCMCPLD"},
				map[string]interface{}{"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/CPU0_PVCCD_HV_VR"},
				map[string]interface{}{"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/CPU1_PVCCIN_VR"},
			},
		},
	}

	signals := CollectSignalsFromTree(tree)
	match := MatchProfiles(signals)

	if match.Mode != ModeMatched {
		t.Fatalf("expected matched mode, got %q", match.Mode)
	}
	assertProfileSelected(t, match, "inspur-group-oem-platforms")
}

func TestCollectSignalsFromTree_InspurGroupOEMPlatformsDoesNotFalsePositiveOnExampleRawExports(t *testing.T) {
	examples := []string{
		"2026-03-18 (G5500 V7) - 210619KUGGXGS2000015.zip",
		"2026-03-11 (SYS-821GE-TNHR) - A514359X5C08846.zip",
		"2026-03-15 (CG480-S5063) - P5T0006091.zip",
		"2026-03-18 (CG290-S3063) - PAT0011258.zip",
		"2024-04-25 (AS -4124GQ-TNMI) - S490387X4418273.zip",
	}
	for _, name := range examples {
		t.Run(name, func(t *testing.T) {
			tree := loadRawExportTreeFromExampleZip(t, name)
			match := MatchProfiles(CollectSignalsFromTree(tree))
			assertProfileNotSelected(t, match, "inspur-group-oem-platforms")
		})
	}
}

func loadRawExportTreeFromExampleZip(t *testing.T, name string) map[string]interface{} {
	t.Helper()
	path := filepath.Join("..", "..", "..", "example", name)
	f, err := os.Open(path)
	if err != nil {
		t.Fatalf("open example zip %s: %v", path, err)
	}
	defer f.Close()

	info, err := f.Stat()
	if err != nil {
		t.Fatalf("stat example zip %s: %v", path, err)
	}

	zr, err := zip.NewReader(f, info.Size())
	if err != nil {
		t.Fatalf("read example zip %s: %v", path, err)
	}
	for _, file := range zr.File {
		if file.Name != "raw_export.json" {
			continue
		}
		rc, err := file.Open()
		if err != nil {
			t.Fatalf("open %s in %s: %v", file.Name, path, err)
		}
		defer rc.Close()
		var payload struct {
			Source struct {
				RawPayloads struct {
					RedfishTree map[string]interface{} `json:"redfish_tree"`
				} `json:"raw_payloads"`
			} `json:"source"`
		}
		if err := json.NewDecoder(rc).Decode(&payload); err != nil {
			t.Fatalf("decode raw_export.json from %s: %v", path, err)
		}
		if len(payload.Source.RawPayloads.RedfishTree) == 0 {
			t.Fatalf("example %s has empty redfish_tree", path)
		}
		return payload.Source.RawPayloads.RedfishTree
	}
	t.Fatalf("raw_export.json not found in %s", path)
	return nil
}
