using System; using System.Collections.Generic; using System.Linq; using System.Text.Json.Serialization; using Lidarr.Http.ClientSchema; using Lidarr.Http.REST; using NzbDrone.Core.CustomFormats; namespace Lidarr.Api.V1.CustomFormats { public class CustomFormatResource : RestResource { [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public override int Id { get; set; } public string Name { get; set; } public bool? IncludeCustomFormatWhenRenaming { get; set; } public List Specifications { get; set; } } public static class CustomFormatResourceMapper { public static CustomFormatResource ToResource(this CustomFormat model, bool includeDetails) { var resource = new CustomFormatResource { Id = model.Id, Name = model.Name }; if (includeDetails) { resource.IncludeCustomFormatWhenRenaming = model.IncludeCustomFormatWhenRenaming; resource.Specifications = model.Specifications.Select(x => x.ToSchema()).ToList(); } return resource; } public static List ToResource(this IEnumerable models, bool includeDetails) { return models.Select(m => m.ToResource(includeDetails)).ToList(); } public static CustomFormat ToModel(this CustomFormatResource resource, List specifications) { return new CustomFormat { Id = resource.Id, Name = resource.Name, IncludeCustomFormatWhenRenaming = resource.IncludeCustomFormatWhenRenaming ?? false, Specifications = resource.Specifications?.Select(x => MapSpecification(x, specifications)).ToList() ?? new List() }; } private static ICustomFormatSpecification MapSpecification(CustomFormatSpecificationSchema resource, List specifications) { var matchingSpec = specifications.SingleOrDefault(x => x.GetType().Name == resource.Implementation); if (matchingSpec is null) { throw new ArgumentException( $"{resource.Implementation} is not a valid specification implementation"); } var type = matchingSpec.GetType(); // Finding the exact current specification isn't possible given the dynamic nature of them and the possibility that multiple // of the same type exist within the same format. Passing in null is safe as long as there never exists a specification that // relies on additional privacy. var spec = (ICustomFormatSpecification)SchemaBuilder.ReadFromSchema(resource.Fields, type, null); spec.Name = resource.Name; spec.Negate = resource.Negate; spec.Required = resource.Required; return spec; } } }