using System.Text; using System.Text.Json; namespace PainoBar_Helper { /// /// Manages Pianobar profiles including creation, deletion, and configuration file generation /// public class ProfileManager { private const string ProfilesFileName = "profiles.json"; private readonly string _profilesFilePath; private List _profiles; private string? _activeProfileName; public ProfileManager() { string appDataPath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "PianobarHelper" ); Directory.CreateDirectory(appDataPath); _profilesFilePath = Path.Combine(appDataPath, ProfilesFileName); _profiles = new List(); LoadProfiles(); } public event EventHandler? ProfilesChanged; public event EventHandler? ActiveProfileChanged; public IReadOnlyList Profiles => _profiles.AsReadOnly(); public string? ActiveProfileName => _activeProfileName; public Profile? GetActiveProfile() { if (string.IsNullOrEmpty(_activeProfileName)) return null; return _profiles.FirstOrDefault(p => p.Name == _activeProfileName); } public void SetActiveProfile(string profileName) { var profile = _profiles.FirstOrDefault(p => p.Name == profileName); if (profile == null) throw new ArgumentException($"Profile '{profileName}' does not exist."); _activeProfileName = profileName; SaveProfiles(); ActiveProfileChanged?.Invoke(this, EventArgs.Empty); } public void CreateProfile(string name, ProfileSettings settings) { if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("Profile name cannot be empty."); if (_profiles.Any(p => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase))) throw new InvalidOperationException($"Profile '{name}' already exists."); var profile = new Profile { Name = name, Settings = settings }; _profiles.Add(profile); if (_profiles.Count == 1) _activeProfileName = name; SaveProfiles(); ProfilesChanged?.Invoke(this, EventArgs.Empty); if (settings.OverrideCredentials && !string.IsNullOrEmpty(settings.ConfigFilePath)) GenerateConfigFile(profile); } public void UpdateProfile(string name, ProfileSettings settings) { var profile = _profiles.FirstOrDefault(p => p.Name == name); if (profile == null) throw new ArgumentException($"Profile '{name}' does not exist."); profile.Settings = settings; SaveProfiles(); ProfilesChanged?.Invoke(this, EventArgs.Empty); if (settings.OverrideCredentials && !string.IsNullOrEmpty(settings.ConfigFilePath)) GenerateConfigFile(profile); } public void DeleteProfile(string name) { var profile = _profiles.FirstOrDefault(p => p.Name == name); if (profile == null) return; _profiles.Remove(profile); if (_activeProfileName == name) { _activeProfileName = _profiles.FirstOrDefault()?.Name; ActiveProfileChanged?.Invoke(this, EventArgs.Empty); } SaveProfiles(); ProfilesChanged?.Invoke(this, EventArgs.Empty); } private void LoadProfiles() { if (!File.Exists(_profilesFilePath)) { _profiles = new List(); return; } try { string json = File.ReadAllText(_profilesFilePath); var data = JsonSerializer.Deserialize(json); if (data != null) { _profiles = data.Profiles ?? new List(); _activeProfileName = data.ActiveProfile; } } catch { _profiles = new List(); } } private void SaveProfiles() { var data = new ProfileData { Profiles = _profiles, ActiveProfile = _activeProfileName }; string json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true }); File.WriteAllText(_profilesFilePath, json); } private void GenerateConfigFile(Profile profile) { var settings = profile.Settings; if (string.IsNullOrEmpty(settings.ConfigFilePath)) return; try { var configDir = Path.GetDirectoryName(settings.ConfigFilePath); if (!string.IsNullOrEmpty(configDir)) Directory.CreateDirectory(configDir); var sb = new StringBuilder(); sb.AppendLine("# Pianobar configuration file"); sb.AppendLine($"# Generated by Pianobar Helper for profile: {profile.Name}"); sb.AppendLine(); if (settings.OverrideCredentials) { if (!string.IsNullOrEmpty(settings.PianobarUser)) sb.AppendLine($"user = {settings.PianobarUser}"); if (!string.IsNullOrEmpty(settings.PianobarPassword)) sb.AppendLine($"password = {settings.PianobarPassword}"); sb.AppendLine(); } File.WriteAllText(settings.ConfigFilePath, sb.ToString()); } catch (Exception ex) { throw new InvalidOperationException($"Failed to generate config file: {ex.Message}", ex); } } public string? GetActiveConfigPath() { var activeProfile = GetActiveProfile(); if (activeProfile?.Settings.OverrideCredentials == true) return activeProfile.Settings.ConfigFilePath; return null; } } public class Profile { public string Name { get; set; } = string.Empty; public ProfileSettings Settings { get; set; } = new ProfileSettings(); } public class ProfileSettings { // Output Settings public bool EnableTextFile { get; set; } public string TextFilePath { get; set; } = string.Empty; public bool EnableWebServer { get; set; } public int WebServerPort { get; set; } = 8080; public bool EnableToastNotifications { get; set; } public bool EnableSMTC { get; set; } // Pianobar Config & Auth public bool OverrideCredentials { get; set; } public string ConfigFilePath { get; set; } = string.Empty; public string PianobarUser { get; set; } = string.Empty; public string PianobarPassword { get; set; } = string.Empty; } internal class ProfileData { public List? Profiles { get; set; } public string? ActiveProfile { get; set; } } }