using System.IO; using Paca.App.Core; using Paca.App.ViewModels; using Paca.Browser; using Paca.Browser.Tabs; using Paca.Core.Config; using Paca.Core.Detection; using Paca.Core.Platform; using Paca.Core.Utils; namespace Paca.Tests.Infrastructure; public sealed class MockPipelineProcessRunner : IProcessRunner { public List Specs { get; } = new(); public Task RunAsync(ProcessSpec spec, Action? onLine, CancellationToken ct) { Specs.Add(spec); return Task.FromResult(new ProcessResult(0, "OK", "")); } } public sealed class MockPipelineCloudStorageClient : ICloudStorageClient { public List UploadedList { get; } = new(); public Task UploadAsync(string localFilePath, string remoteDestination, Action? onProgress, CancellationToken ct) { UploadedList.Add($"{localFilePath} -> {remoteDestination}"); return Task.FromResult(true); } public Task ExistsAsync(string remoteDestination, CancellationToken ct) { return Task.FromResult(UploadedList.Any(u => u.EndsWith(remoteDestination))); } } /// /// 40개 마일스톤 전 영역 통합 오케스트레이션 파이프라인 하네스. /// public sealed class GrandUnifiedPipeline : IDisposable { public string TempDir { get; } public AppConfig Config { get; } public TabManager TabManager { get; } public AdBlockRuleEngine AdBlockEngine { get; } public MemoryTurboGuard MemoryGuard { get; } public DownloadManager DownloadManager { get; } public VideoDeduplicator Deduplicator { get; } public QoSTrafficShaper TrafficShaper { get; } public ChaosMonkeyStressDefense ChaosDefense { get; } public AudioNormalizer AudioNormalizer { get; } public HdrToneMapper HdrToneMapper { get; } public ChapterSplitter ChapterSplitter { get; } public DualSubtitleEngine DualSubtitleEngine { get; } public CloudSyncGateway CloudGateway { get; } public MockPipelineProcessRunner ProcessRunner { get; } public MockPipelineCloudStorageClient CloudClient { get; } private readonly List _detectedItems = new(); private GrandUnifiedPipeline() { TempDir = Path.Combine(Path.GetTempPath(), "VD_Grand_" + Guid.NewGuid().ToString("N")); Directory.CreateDirectory(TempDir); Config = new AppConfig { OutputFolder = Path.Combine(TempDir, "downloads") }; Directory.CreateDirectory(Config.OutputFolder); ProcessRunner = new MockPipelineProcessRunner(); CloudClient = new MockPipelineCloudStorageClient(); TabManager = new TabManager(() => new TabItem(), _ => { }); AdBlockEngine = new AdBlockRuleEngine(); MemoryGuard = new MemoryTurboGuard(TimeSpan.FromMinutes(10)); DownloadManager = new DownloadManager( Config, _ => Task.FromResult(new List()), _ => { }); DownloadManager.ItemDetected += item => _detectedItems.Add(item); Deduplicator = new VideoDeduplicator(maxHammingThreshold: 5); TrafficShaper = new QoSTrafficShaper(maxBandwidthBytesPerSec: 10_000_000); ChaosDefense = new ChaosMonkeyStressDefense(failureRate: 0.3); AudioNormalizer = new AudioNormalizer(ProcessRunner); HdrToneMapper = new HdrToneMapper(ProcessRunner); ChapterSplitter = new ChapterSplitter(ProcessRunner); DualSubtitleEngine = new DualSubtitleEngine(); CloudGateway = new CloudSyncGateway(CloudClient); } public static GrandUnifiedPipeline Create() => new(); public IReadOnlyList DetectedItems => _detectedItems; public void SimulateWebRequest(string url, MediaKind? mediaKind = null, string? pageUrl = null) { var uri = new Uri(url); // 1. 광고 차단 검사 if (AdBlockEngine.ShouldBlock(uri)) return; // 2. 미디어 감지 if (mediaKind.HasValue) { DownloadManager.OnDetected(new DetectionContext(url, pageUrl ?? "https://test.local", mediaKind.Value)); } } public void Dispose() { if (Directory.Exists(TempDir)) { try { Directory.Delete(TempDir, true); } catch { } } } }