using System.ComponentModel.DataAnnotations.Schema; using System.Text.Json.Serialization; using Cleanuparr.Domain.Enums; using Cleanuparr.Domain.Exceptions; using Cleanuparr.Shared.Attributes; namespace Cleanuparr.Persistence.Models.Configuration; /// /// Configuration for a specific download client /// [Table("download_clients")] public sealed record DownloadClientConfig { /// /// Unique identifier for this client /// [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid Id { get; init; } = Guid.NewGuid(); /// /// Whether this client is enabled /// public bool Enabled { get; init; } = false; /// /// Friendly name for this client /// public required string Name { get; init; } /// /// Type name of download client /// public required DownloadClientTypeName TypeName { get; init; } /// /// Type of download client /// public required DownloadClientType Type { get; init; } /// /// Host address for the download client /// public Uri? Host { get; init; } /// /// Username for authentication /// [SensitiveData] public string? Username { get; init; } /// /// Password for authentication /// [SensitiveData] public string? Password { get; init; } /// /// The base URL path component, used by clients like Transmission and Deluge /// public string? UrlBase { get; init; } /// /// The computed full URL for the client /// [NotMapped] [JsonIgnore] public Uri Url => new($"{Host?.ToString().TrimEnd('/')}/{UrlBase?.TrimStart('/').TrimEnd('/')}"); /// /// Validates the configuration /// public void Validate() { if (string.IsNullOrWhiteSpace(Name)) { throw new ValidationException($"Client name cannot be empty"); } if (Host is null) { throw new ValidationException($"Host cannot be empty"); } } }