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; }
}
}