using System.Windows.Threading;
using VideoDownloader.App.ViewModels;
using VideoDownloader.Server;
using VideoDownloader.Core.Detection;
namespace VideoDownloader.App.Services;
///
/// DownloadManager(UI 컬렉션) ↔ 서버 큐 API 브릿지. 모든 접근을 UI 디스패처로 마샬링.
///
public sealed class DownloadQueueAdapter : IQueueAdapter
{
private readonly Core.DownloadManager _manager;
private readonly Dispatcher _dispatcher;
public DownloadQueueAdapter(Core.DownloadManager manager, Dispatcher dispatcher)
{
_manager = manager;
_dispatcher = dispatcher;
}
public Task> GetItemsAsync() => _dispatcher.InvokeAsync(() =>
(IReadOnlyList)_manager.Items.Select(Map).ToList()).Task;
public Task AddAsync(string url, string? title)
{
// 서버에서 온 URL → 감지 파이프라인으로(소셜/HLS/DASH 자동 분류)
return _dispatcher.InvokeAsync(() =>
{
if (Uri.TryCreate(url, UriKind.Absolute, out var uri) &&
SocialSiteDetector.TryMatch(uri, out var normalized, out var label))
{
_manager.OnDetected(new DetectionContext(normalized, normalized, MediaKind.Social, Tag: label));
return normalized;
}
var kind = MediaDetector.Classify(url, "", -1, _manager.Config) ?? MediaKind.Direct;
_manager.OnDetected(new DetectionContext(url, url, kind, ""));
return url;
}).Task;
}
public Task PauseAsync(string id) => _dispatcher.InvokeAsync(() =>
{
var item = Find(id);
if (item != null) _manager.Cancel(item); // v1: 제어 매핑 — 진행 항목 취소
}).Task;
public Task ResumeAsync(string id) => _dispatcher.InvokeAsync(() =>
{
var item = Find(id);
if (item != null) _ = _manager.RetryDownload(item);
}).Task;
public Task CancelAsync(string id) => _dispatcher.InvokeAsync(() =>
{
var item = Find(id);
if (item != null) _manager.Cancel(item);
}).Task;
public event Action? Changed { add { } remove { } }
private DownloadItemViewModel? Find(string id) =>
_manager.Items.FirstOrDefault(i => i.Id == id);
private static QueueItemDto Map(DownloadItemViewModel i) =>
new(i.Id, i.Title, i.Url ?? "", i.Status ?? "", i.Progress);
}