using CloudPrint.Client.Models; using CloudPrint.Client.Services.Abstractions; using System.IO; namespace CloudPrint.Client.Services; public sealed class PrintJobCoordinator { private readonly IFileService _fileService; private readonly IPrintService _printService; private readonly IPrintBackendClient _backendClient; public PrintJobCoordinator(IFileService fileService, IPrintService printService, IPrintBackendClient backendClient) { _fileService = fileService; _printService = printService; _backendClient = backendClient; } public async Task ProcessAsync(PrintJob job, ClientSettings settings, IProgress? progress = null, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(job); ArgumentNullException.ThrowIfNull(settings); try { job.MarkPrinting(); await _backendClient.SendStatusUpdateAsync(job, cancellationToken).ConfigureAwait(true); if ((string.IsNullOrWhiteSpace(job.FilePath) || !File.Exists(job.FilePath)) && job.FileId > 0) { job.FilePath = await _backendClient.DownloadPrintFileAsync(job, settings.PrintCacheRoot, cancellationToken).ConfigureAwait(true); } var preparationResult = await _fileService.PrepareForPrintAsync(job, settings.PrintCacheRoot, cancellationToken).ConfigureAwait(true); job.FilePath = preparationResult.PreparedPath; var forwardingProgress = new Progress(async value => { job.Progress = value; if (value >= 100) { job.MarkCompleted(); } progress?.Report(value); await _backendClient.SendStatusUpdateAsync(job, cancellationToken).ConfigureAwait(true); }); await _printService.SubmitPrintJobAsync(job, forwardingProgress, cancellationToken).ConfigureAwait(true); job.MarkCompleted(); await _backendClient.SendStatusUpdateAsync(job, cancellationToken).ConfigureAwait(true); } catch (OperationCanceledException) { job.MarkCancelled(); await _backendClient.SendStatusUpdateAsync(job, CancellationToken.None).ConfigureAwait(true); throw; } catch (Exception ex) { job.MarkFailed(ex.Message); await _backendClient.SendStatusUpdateAsync(job, CancellationToken.None).ConfigureAwait(true); throw; } } }