package config import ( "encoding/json" "fmt" "os" "path/filepath" ) type Config struct { APIBaseURL string `json:"api_base_url"` TimeoutSec int `json:"timeout_sec"` RateLimitReq int `json:"rate_limit_requests"` RateLimitWin int `json:"rate_limit_window_sec"` } type ConfigManager struct { configDir string configFile string } func NewConfigManager() *ConfigManager { homeDir, err := os.UserHomeDir() if err != nil { homeDir = "~" } configDir := filepath.Join(homeDir, ".config", "pop") return &ConfigManager{ configDir: configDir, configFile: filepath.Join(configDir, "config.json"), } } func (m *ConfigManager) ConfigDir() string { return m.configDir } func (m *ConfigManager) Load() (*Config, error) { defaultConfig := &Config{ APIBaseURL: "https://api.protonmail.ch", TimeoutSec: 30, RateLimitReq: 100, RateLimitWin: 60, } data, err := os.ReadFile(m.configFile) if err != nil { if os.IsNotExist(err) { return defaultConfig, nil } return nil, fmt.Errorf("failed to read config: %w", err) } var config Config if err := json.Unmarshal(data, &config); err != nil { return nil, fmt.Errorf("failed to parse config: %w", err) } return &config, nil } func (m *ConfigManager) Save(config *Config) error { if err := os.MkdirAll(m.configDir, 0755); err != nil { return fmt.Errorf("failed to create config dir: %w", err) } data, err := json.MarshalIndent(config, "", " ") if err != nil { return fmt.Errorf("failed to marshal config: %w", err) } if err := os.WriteFile(m.configFile, data, 0600); err != nil { return fmt.Errorf("failed to write config file: %w", err) } return nil }