package core import ( "encoding/json" "fmt" "os" "path/filepath" ) // ConfigManager handles saving/loading VPN configs to disk. type ConfigManager struct { configFilePath string } // NewConfigManager creates a new ConfigManager with config file under %APPDATA%/kettuRay. func NewConfigManager() (*ConfigManager, error) { appData, err := os.UserConfigDir() if err != nil { return nil, fmt.Errorf("failed to get app data dir: %w", err) } appDir := filepath.Join(appData, "kettuRay") if err := os.MkdirAll(appDir, 0o755); err != nil { return nil, fmt.Errorf("failed to create app dir: %w", err) } return &ConfigManager{ configFilePath: filepath.Join(appDir, "configs.json"), }, nil } // LoadConfigs loads saved VPN configs from disk. func (m *ConfigManager) LoadConfigs() ([]VpnConfig, error) { data, err := os.ReadFile(m.configFilePath) if err != nil { if os.IsNotExist(err) { return make([]VpnConfig, 0), nil } return nil, err } var configs []VpnConfig if len(data) == 0 { return make([]VpnConfig, 0), nil } if err := json.Unmarshal(data, &configs); err != nil { fmt.Printf("Error parsing configs.json: %v\n", err) // return empty slice but still error so app knows it failed return make([]VpnConfig, 0), err } return configs, nil } // SaveConfigs writes VPN configs to disk. func (m *ConfigManager) SaveConfigs(configs []VpnConfig) error { data, err := json.MarshalIndent(configs, "", " ") if err != nil { return fmt.Errorf("failed to marshal configs: %w", err) } return os.WriteFile(m.configFilePath, data, 0o644) }