Files
WiseTLP/internal/config/preferences.go
2025-09-16 14:27:34 +03:00

347 lines
12 KiB
Go

package config
import (
"fmt"
"strings"
"git.gostacks.org/iwasforcedtobehere/WiseTLP/autotlp/pkg/types"
"git.gostacks.org/iwasforcedtobehere/WiseTLP/autotlp/pkg/utils"
)
// Config represents the application configuration
type Config struct {
// Application-wide configuration settings
}
// New creates a new configuration instance
func New() *Config {
return &Config{}
}
// GatherUserPreferences interactively collects user preferences
func GatherUserPreferences() (*types.UserPreferences, error) {
fmt.Println("\n" + strings.Repeat("=", 60))
fmt.Println("USER PREFERENCES CONFIGURATION")
fmt.Println(strings.Repeat("=", 60))
preferences := &types.UserPreferences{
CustomSettings: make(map[string]interface{}),
SpecialRequirements: []string{},
}
// Power Profile
fmt.Println("\n1. Power Profile Selection")
fmt.Println("Choose your preferred power management approach:")
fmt.Println(" a) Balanced - Good compromise between performance and power saving")
fmt.Println(" b) Performance - Maximum performance, higher power consumption")
fmt.Println(" c) Power Saving - Maximum battery life, reduced performance")
fmt.Println(" d) Custom - I'll specify custom requirements")
profileChoice := utils.GetUserInput("Select power profile (a/b/c/d)", "a")
switch strings.ToLower(profileChoice) {
case "a", "balanced":
preferences.PowerProfile = types.PowerProfileBalanced
case "b", "performance":
preferences.PowerProfile = types.PowerProfilePerformance
case "c", "power saving", "powersaving":
preferences.PowerProfile = types.PowerProfilePowerSaving
case "d", "custom":
preferences.PowerProfile = types.PowerProfileCustom
default:
preferences.PowerProfile = types.PowerProfileBalanced
}
// Use Case
fmt.Println("\n2. Primary Use Case")
fmt.Println("What do you primarily use this system for?")
fmt.Println(" a) General use - Web browsing, office work, media consumption")
fmt.Println(" b) Development - Programming, compiling, development tools")
fmt.Println(" c) Gaming - Gaming and graphics-intensive applications")
fmt.Println(" d) Server - Server workloads, always-on services")
fmt.Println(" e) Multimedia - Video editing, rendering, content creation")
fmt.Println(" f) Office - Primarily office applications and productivity")
useCaseChoice := utils.GetUserInput("Select use case (a/b/c/d/e/f)", "a")
switch strings.ToLower(useCaseChoice) {
case "a", "general":
preferences.UseCase = types.UseCaseGeneral
case "b", "development", "dev":
preferences.UseCase = types.UseCaseDevelopment
case "c", "gaming":
preferences.UseCase = types.UseCaseGaming
case "d", "server":
preferences.UseCase = types.UseCaseServer
case "e", "multimedia", "media":
preferences.UseCase = types.UseCaseMultimedia
case "f", "office":
preferences.UseCase = types.UseCaseOffice
default:
preferences.UseCase = types.UseCaseGeneral
}
// Battery Priority (only for systems with batteries)
fmt.Println("\n3. Battery Optimization Priority")
fmt.Println("How would you like to optimize battery usage?")
fmt.Println(" a) Balanced - Balance between battery life and longevity")
fmt.Println(" b) Runtime - Maximize single-charge runtime")
fmt.Println(" c) Longevity - Maximize battery lifespan over years")
batteryChoice := utils.GetUserInput("Select battery priority (a/b/c)", "a")
switch strings.ToLower(batteryChoice) {
case "a", "balanced":
preferences.BatteryPriority = types.BatteryPriorityBalanced
case "b", "runtime":
preferences.BatteryPriority = types.BatteryPriorityRuntime
case "c", "longevity":
preferences.BatteryPriority = types.BatteryPriorityLongevity
default:
preferences.BatteryPriority = types.BatteryPriorityBalanced
}
// Performance Mode
fmt.Println("\n4. Performance Mode")
fmt.Println("How should the system handle performance scaling?")
fmt.Println(" a) Adaptive - Automatically adjust based on workload")
fmt.Println(" b) Maximum - Always prefer maximum performance")
fmt.Println(" c) Efficient - Always prefer energy efficiency")
perfChoice := utils.GetUserInput("Select performance mode (a/b/c)", "a")
switch strings.ToLower(perfChoice) {
case "a", "adaptive":
preferences.PerformanceMode = types.PerformanceModeAdaptive
case "b", "maximum", "max":
preferences.PerformanceMode = types.PerformanceModeMaximum
case "c", "efficient", "efficiency":
preferences.PerformanceMode = types.PerformanceModeEfficient
default:
preferences.PerformanceMode = types.PerformanceModeAdaptive
}
// Special Requirements
fmt.Println("\n5. Special Requirements")
fmt.Println("Do you have any special requirements? (Select all that apply)")
fmt.Println(" a) Minimize fan noise")
fmt.Println(" b) Prevent thermal throttling")
fmt.Println(" c) Optimize for external displays")
fmt.Println(" d) Gaming performance priority")
fmt.Println(" e) Maximum WiFi performance")
fmt.Println(" f) Minimize disk wear")
fmt.Println(" g) Fast system wake/sleep")
fmt.Println(" h) None of the above")
requirements := utils.GetUserInput("Enter letters separated by spaces (e.g., 'a c f')", "h")
if strings.ToLower(requirements) != "h" {
reqMap := map[string]string{
"a": "Minimize fan noise",
"b": "Prevent thermal throttling",
"c": "Optimize for external displays",
"d": "Gaming performance priority",
"e": "Maximum WiFi performance",
"f": "Minimize disk wear",
"g": "Fast system wake/sleep",
}
reqLetters := strings.Fields(strings.ToLower(requirements))
for _, letter := range reqLetters {
if req, exists := reqMap[letter]; exists {
preferences.SpecialRequirements = append(preferences.SpecialRequirements, req)
}
}
}
// Custom Settings (for advanced users)
if preferences.PowerProfile == types.PowerProfileCustom {
fmt.Println("\n6. Custom Settings")
fmt.Println("You selected custom power profile. You can specify additional settings.")
if utils.GetUserConfirmation("Do you want to specify custom CPU governor settings?") {
acGovernor := utils.GetUserInput("CPU governor on AC power (performance/powersave/ondemand/conservative/schedutil)", "performance")
batGovernor := utils.GetUserInput("CPU governor on battery (performance/powersave/ondemand/conservative/schedutil)", "powersave")
preferences.CustomSettings["cpu_governor_ac"] = acGovernor
preferences.CustomSettings["cpu_governor_battery"] = batGovernor
}
if utils.GetUserConfirmation("Do you want to specify custom disk settings?") {
diskAPMAC := utils.GetUserInput("Disk APM level on AC (1-255, higher = more aggressive)", "254")
diskAPMBat := utils.GetUserInput("Disk APM level on battery (1-255, higher = more aggressive)", "128")
preferences.CustomSettings["disk_apm_ac"] = diskAPMAC
preferences.CustomSettings["disk_apm_battery"] = diskAPMBat
}
}
// Summary
fmt.Println("\n" + strings.Repeat("-", 60))
fmt.Println("PREFERENCES SUMMARY")
fmt.Println(strings.Repeat("-", 60))
fmt.Printf("Power Profile: %s\n", preferences.PowerProfile)
fmt.Printf("Use Case: %s\n", preferences.UseCase)
fmt.Printf("Battery Priority: %s\n", preferences.BatteryPriority)
fmt.Printf("Performance Mode: %s\n", preferences.PerformanceMode)
if len(preferences.SpecialRequirements) > 0 {
fmt.Printf("Special Requirements: %s\n", strings.Join(preferences.SpecialRequirements, ", "))
}
if len(preferences.CustomSettings) > 0 {
fmt.Println("Custom Settings:")
for key, value := range preferences.CustomSettings {
fmt.Printf(" %s: %v\n", key, value)
}
}
fmt.Println(strings.Repeat("-", 60))
if !utils.GetUserConfirmation("Are these preferences correct?") {
fmt.Println("Let's try again...")
return GatherUserPreferences()
}
return preferences, nil
}
// ValidatePreferences validates user preferences for consistency
func ValidatePreferences(preferences *types.UserPreferences) error {
if preferences == nil {
return fmt.Errorf("preferences cannot be nil")
}
// Validate power profile
validProfiles := []types.PowerProfile{
types.PowerProfileBalanced,
types.PowerProfilePerformance,
types.PowerProfilePowerSaving,
types.PowerProfileCustom,
}
validProfile := false
for _, profile := range validProfiles {
if preferences.PowerProfile == profile {
validProfile = true
break
}
}
if !validProfile {
return fmt.Errorf("invalid power profile: %s", preferences.PowerProfile)
}
// Validate use case
validUseCases := []types.UseCase{
types.UseCaseGeneral,
types.UseCaseDevelopment,
types.UseCaseGaming,
types.UseCaseServer,
types.UseCaseMultimedia,
types.UseCaseOffice,
}
validUseCase := false
for _, useCase := range validUseCases {
if preferences.UseCase == useCase {
validUseCase = true
break
}
}
if !validUseCase {
return fmt.Errorf("invalid use case: %s", preferences.UseCase)
}
// Check for conflicting preferences
if preferences.PowerProfile == types.PowerProfilePowerSaving &&
preferences.PerformanceMode == types.PerformanceModeMaximum {
return fmt.Errorf("conflicting preferences: power saving profile with maximum performance mode")
}
if preferences.UseCase == types.UseCaseGaming &&
preferences.PowerProfile == types.PowerProfilePowerSaving {
fmt.Println("⚠️ Warning: Gaming use case with power saving profile may impact performance")
}
return nil
}
// GetRecommendedSettings provides recommended settings based on preferences
func GetRecommendedSettings(preferences *types.UserPreferences) map[string]string {
settings := make(map[string]string)
// Base settings
settings["TLP_ENABLE"] = "1"
settings["TLP_WARN_LEVEL"] = "3"
// CPU settings based on power profile and use case
switch preferences.PowerProfile {
case types.PowerProfilePerformance:
settings["CPU_SCALING_GOVERNOR_ON_AC"] = "performance"
settings["CPU_SCALING_GOVERNOR_ON_BAT"] = "performance"
case types.PowerProfilePowerSaving:
settings["CPU_SCALING_GOVERNOR_ON_AC"] = "powersave"
settings["CPU_SCALING_GOVERNOR_ON_BAT"] = "powersave"
default: // Balanced
settings["CPU_SCALING_GOVERNOR_ON_AC"] = "performance"
settings["CPU_SCALING_GOVERNOR_ON_BAT"] = "powersave"
}
// Adjust for use case
switch preferences.UseCase {
case types.UseCaseGaming:
settings["CPU_SCALING_GOVERNOR_ON_AC"] = "performance"
settings["PLATFORM_PROFILE_ON_AC"] = "performance"
settings["PLATFORM_PROFILE_ON_BAT"] = "balanced"
case types.UseCaseServer:
settings["CPU_SCALING_GOVERNOR_ON_AC"] = "performance"
settings["CPU_SCALING_GOVERNOR_ON_BAT"] = "performance"
settings["PLATFORM_PROFILE_ON_AC"] = "performance"
settings["PLATFORM_PROFILE_ON_BAT"] = "performance"
case types.UseCaseDevelopment:
settings["CPU_SCALING_GOVERNOR_ON_AC"] = "ondemand"
settings["CPU_SCALING_GOVERNOR_ON_BAT"] = "powersave"
}
// Disk settings based on battery priority
switch preferences.BatteryPriority {
case types.BatteryPriorityRuntime:
settings["DISK_APM_LEVEL_ON_BAT"] = "1"
settings["DISK_SPINDOWN_TIMEOUT_ON_BAT"] = "60"
case types.BatteryPriorityLongevity:
settings["DISK_APM_LEVEL_ON_BAT"] = "128"
settings["DISK_SPINDOWN_TIMEOUT_ON_BAT"] = "0"
default: // Balanced
settings["DISK_APM_LEVEL_ON_BAT"] = "128"
settings["DISK_SPINDOWN_TIMEOUT_ON_BAT"] = "120"
}
settings["DISK_APM_LEVEL_ON_AC"] = "254"
settings["DISK_SPINDOWN_TIMEOUT_ON_AC"] = "0"
// Network settings
if utils.Contains(preferences.SpecialRequirements, "Maximum WiFi performance") {
settings["WIFI_PWR_ON_AC"] = "off"
settings["WIFI_PWR_ON_BAT"] = "off"
} else {
settings["WIFI_PWR_ON_AC"] = "off"
settings["WIFI_PWR_ON_BAT"] = "on"
}
// USB settings
settings["USB_AUTOSUSPEND"] = "1"
// Apply custom settings
for key, value := range preferences.CustomSettings {
switch key {
case "cpu_governor_ac":
settings["CPU_SCALING_GOVERNOR_ON_AC"] = fmt.Sprintf("%v", value)
case "cpu_governor_battery":
settings["CPU_SCALING_GOVERNOR_ON_BAT"] = fmt.Sprintf("%v", value)
case "disk_apm_ac":
settings["DISK_APM_LEVEL_ON_AC"] = fmt.Sprintf("%v", value)
case "disk_apm_battery":
settings["DISK_APM_LEVEL_ON_BAT"] = fmt.Sprintf("%v", value)
}
}
return settings
}