using Beam.Abstractions; using Beam.Models; using HtmlAgilityPack; using Microsoft.Extensions.Logging; namespace Beam.Downloaders { public class DownloadContextBuilder { private HtmlWeb _web; private HttpClient _client; private IProgress? _downloadReporter; private IProgress? _retryReporter; private AsyncDownloadFailurePredicate?[] _asyncFailurePredicates = []; private TimeSpan _timeOut; private IEnumerable _links; private CancellationToken _cancellationToken; private DocumentCache _cache; private ILogger? _downloadLogger; public DownloadContextBuilder(HttpClient? client = null, HtmlWeb? web = null) { // You can initialize defaults here if needed, e.g.: // _timeOut = TimeSpan.FromSeconds(30); // _cancellationToken = CancellationToken.None; _client = client ?? new(); _web = web ?? new(); _links = []; } public DownloadContextBuilder WithWeb(HtmlWeb web) { _web = web; return this; } public DownloadContextBuilder WithClient(HttpClient client) { _client = client; return this; } public DownloadContextBuilder WithDownloadReporter(IProgress downloadReporter) { _downloadReporter = downloadReporter; return this; } public DownloadContextBuilder WithRetryReporter(IProgress retryReporter) { _retryReporter = retryReporter; return this; } public DownloadContextBuilder WithAsyncFailurePredicates(params AsyncDownloadFailurePredicate[] predicates) { _asyncFailurePredicates = predicates; return this; } public DownloadContextBuilder WithTimeOut(TimeSpan timeOut) { _timeOut = timeOut; return this; } public DownloadContextBuilder WithLinks(IEnumerable links) { _links = links; return this; } public DownloadContextBuilder WithCancellationToken(CancellationToken cancellationToken) { _cancellationToken = cancellationToken; return this; } public DownloadContextBuilder WithCache(DocumentCache cache) { _cache = cache; return this; } public DownloadContextBuilder WithDownloadLogger(ILogger downloadLogger) { _downloadLogger = downloadLogger; return this; } public DownloadContext Build() { // Construct the DownloadContext using the collected values. var context = new DownloadContext( web: _web, client: _client, links: _links, cancellationToken: _cancellationToken, downloadReporter: _downloadReporter, retryReporter: _retryReporter, asyncFailurePredicates: _asyncFailurePredicates, timeOut: _timeOut, downloadLogger: _downloadLogger ); //// Assign the DocumentCache if it's been set in the builder. //// (Even though Cache has a private setter, this code assumes builder //// is in the same assembly or that the setter will be made internal. //// Otherwise, remove or adjust this line.) //context.Cache = _cache; return context; } public static DownloadContextBuilder FromContext(DownloadContext existing) { if (existing == null) throw new ArgumentNullException(nameof(existing)); return new DownloadContextBuilder(existing.Client, existing.Web) .WithLinks(existing.Links) .WithCancellationToken(existing.CancellationToken) .WithDownloadReporter(existing.DownloadReporter!) .WithRetryReporter(existing.RetryReporter!) .WithAsyncFailurePredicates(existing.AsyncFailurePredicates ?? Array.Empty>()) .WithTimeOut(existing.TimeOut) .WithDownloadLogger(existing.DownloadLogger!) .WithCache(existing.Cache); } } }