package redfishprofile

import "strings"

func ResolveAnalysisPlan(match MatchResult, snapshot map[string]interface{}, discovered DiscoveredResources, signals MatchSignals) ResolvedAnalysisPlan {
	plan := ResolvedAnalysisPlan{
		Match:      match,
		Directives: AnalysisDirectives{},
	}
	if match.Mode == ModeFallback {
		plan.Directives.EnableProcessorGPUFallback = true
		plan.Directives.EnableSupermicroNVMeBackplane = true
		plan.Directives.EnableProcessorGPUChassisAlias = true
		plan.Directives.EnableGenericGraphicsControllerDedup = true
		plan.Directives.EnableStorageEnclosureRecovery = true
		plan.Directives.EnableKnownStorageControllerRecovery = true
		addAnalysisLookupMode(&plan, "msi-index")
		addAnalysisLookupMode(&plan, "hgx-alias")
		addAnalysisStorageDriveCollections(&plan,
			"/Storage/IntelVROC/Drives",
			"/Storage/IntelVROC/Controllers/1/Drives",
		)
		addAnalysisStorageVolumeCollections(&plan,
			"/Storage/IntelVROC/Volumes",
			"/Storage/HA-RAID/Volumes",
			"/Storage/MRVL.HA-RAID/Volumes",
		)
		addAnalysisNote(&plan, "fallback analysis enables broad recovery directives")
	}
	for _, profile := range match.Profiles {
		profile.ApplyAnalysisDirectives(&plan.Directives, signals)
	}
	for _, profile := range match.Profiles {
		profile.RefineAnalysisPlan(&plan, snapshot, discovered, signals)
	}
	return plan
}

func snapshotHasPathPrefix(snapshot map[string]interface{}, prefix string) bool {
	prefix = normalizePath(prefix)
	if prefix == "" {
		return false
	}
	for path := range snapshot {
		if strings.HasPrefix(normalizePath(path), prefix) {
			return true
		}
	}
	return false
}

func snapshotHasPathContaining(snapshot map[string]interface{}, sub string) bool {
	sub = strings.ToLower(strings.TrimSpace(sub))
	if sub == "" {
		return false
	}
	for path := range snapshot {
		if strings.Contains(strings.ToLower(path), sub) {
			return true
		}
	}
	return false
}

func snapshotHasGPUProcessor(snapshot map[string]interface{}, systemPaths []string) bool {
	for _, systemPath := range systemPaths {
		prefix := normalizePath(joinPath(systemPath, "/Processors")) + "/"
		for path, docAny := range snapshot {
			if !strings.HasPrefix(normalizePath(path), prefix) {
				continue
			}
			doc, ok := docAny.(map[string]interface{})
			if !ok {
				continue
			}
			if strings.EqualFold(strings.TrimSpace(asString(doc["ProcessorType"])), "GPU") {
				return true
			}
		}
	}
	return false
}

func snapshotHasStorageControllerHint(snapshot map[string]interface{}, needles ...string) bool {
	for _, needle := range needles {
		if snapshotHasPathContaining(snapshot, needle) {
			return true
		}
	}
	return false
}

func asString(v interface{}) string {
	switch x := v.(type) {
	case string:
		return x
	default:
		return ""
	}
}
