package collector

import (
	"strings"

	"git.mchus.pro/mchus/logpile/internal/collector/redfishprofile"
)

func (r redfishSnapshotReader) collectKnownStorageMembers(systemPath string, relativeCollections []string) []map[string]interface{} {
	var out []map[string]interface{}
	for _, rel := range relativeCollections {
		docs, err := r.getCollectionMembers(joinPath(systemPath, rel))
		if err != nil || len(docs) == 0 {
			continue
		}
		out = append(out, docs...)
	}
	return out
}

func (r redfishSnapshotReader) probeSupermicroNVMeDiskBays(backplanePath string) []map[string]interface{} {
	return r.probeDirectDiskBayChildren(joinPath(backplanePath, "/Drives"))
}

func (r redfishSnapshotReader) probeDirectDiskBayChildren(drivesCollectionPath string) []map[string]interface{} {
	var out []map[string]interface{}
	for _, path := range directDiskBayCandidates(drivesCollectionPath) {
		doc, err := r.getJSON(path)
		if err != nil || !looksLikeDrive(doc) {
			continue
		}
		out = append(out, doc)
	}
	return out
}

func resolveProcessorGPUChassisSerial(chassisByID map[string]map[string]interface{}, gpuID string, plan redfishprofile.ResolvedAnalysisPlan) string {
	for _, candidateID := range processorGPUChassisCandidateIDs(gpuID, plan) {
		if chassisDoc, ok := chassisByID[strings.ToUpper(candidateID)]; ok {
			if serial := strings.TrimSpace(asString(chassisDoc["SerialNumber"])); serial != "" {
				return serial
			}
		}
	}
	return ""
}

func resolveProcessorGPUChassisPath(chassisPathByID map[string]string, gpuID string, plan redfishprofile.ResolvedAnalysisPlan) string {
	for _, candidateID := range processorGPUChassisCandidateIDs(gpuID, plan) {
		if p, ok := chassisPathByID[strings.ToUpper(candidateID)]; ok {
			return p
		}
	}
	return ""
}

func processorGPUChassisCandidateIDs(gpuID string, plan redfishprofile.ResolvedAnalysisPlan) []string {
	gpuID = strings.TrimSpace(gpuID)
	if gpuID == "" {
		return nil
	}
	candidates := []string{gpuID}
	for _, mode := range plan.ProcessorGPUChassisLookupModes {
		switch strings.ToLower(strings.TrimSpace(mode)) {
		case "msi-index":
			candidates = append(candidates, msiProcessorGPUChassisCandidateIDs(gpuID)...)
		case "hgx-alias":
			if strings.HasPrefix(strings.ToUpper(gpuID), "GPU_") {
				candidates = append(candidates, "HGX_"+gpuID)
			}
		}
	}
	return dedupeStrings(candidates)
}

func msiProcessorGPUChassisCandidateIDs(gpuID string) []string {
	gpuID = strings.TrimSpace(strings.ToUpper(gpuID))
	if gpuID == "" {
		return nil
	}
	var out []string
	switch {
	case strings.HasPrefix(gpuID, "GPU_SXM_"):
		index := strings.TrimPrefix(gpuID, "GPU_SXM_")
		if index != "" {
			out = append(out, "GPU"+index, "GPU_"+index)
		}
	case strings.HasPrefix(gpuID, "GPU_"):
		index := strings.TrimPrefix(gpuID, "GPU_")
		if index != "" {
			out = append(out, "GPU"+index, "GPU_SXM_"+index)
		}
	case strings.HasPrefix(gpuID, "GPU"):
		index := strings.TrimPrefix(gpuID, "GPU")
		if index != "" {
			out = append(out, "GPU_"+index, "GPU_SXM_"+index)
		}
	}
	return out
}
