using EmbyToolbox.Models; namespace EmbyToolbox.Services; public sealed class BulkTrackSettingsService { private readonly TrackStructureComparer _comparer = new(); public BulkTrackSelectionAnalysis Analyze(IReadOnlyList selected) { var candidates = selected .Where(i => i.MediaAnalysis is not null && i.TaskOverride.TrackOverrides.Count > 0) .ToList(); if (candidates.Count < 2) { return BulkTrackSelectionAnalysis.Empty; } var groups = candidates .GroupBy(i => _comparer.BuildSignature(i.TaskOverride.TrackOverrides)) .Select(g => new { Signature = g.Key, Items = g.OrderBy(i => i.OrderNumber).ToList() }) .OrderByDescending(g => g.Items.Count) .ThenBy(g => g.Items[0].OrderNumber) .ToList(); if (groups.Count == 0) { return BulkTrackSelectionAnalysis.Empty; } var top = groups[0]; if (groups.Count > 1 && groups[1].Items.Count == top.Items.Count) { return new BulkTrackSelectionAnalysis(null, [], candidates.OrderBy(i => i.OrderNumber).ToList(), false); } var skipped = candidates.Except(top.Items).OrderBy(i => i.OrderNumber).ToList(); return new BulkTrackSelectionAnalysis(top.Signature, top.Items, skipped, true); } public void ApplyBulkEdits( IReadOnlyList targets, IReadOnlyList editedTemplateTracks) { foreach (var item in targets) { if (item.TaskOverride.TrackOverrides.Count != editedTemplateTracks.Count) { continue; } for (var i = 0; i < editedTemplateTracks.Count; i++) { var dst = item.TaskOverride.TrackOverrides[i]; var src = editedTemplateTracks[i]; dst.Action = src.Action; dst.AudioBitrateKbps = src.AudioBitrateKbps; dst.Default = src.Default; dst.Language = src.Language; dst.Title = src.Title; } } } } public sealed record BulkTrackSelectionAnalysis( string? MajoritySignature, IReadOnlyList MajorityItems, IReadOnlyList SkippedItems, bool HasMajority) { public static BulkTrackSelectionAnalysis Empty { get; } = new(null, [], [], false); }