using DocumentOperator.Application.Common.DTOs; namespace DocumentOperator.Application.Common.Interfaces; public interface IPdfProcessor { /// /// Validates a PDF and extracts metadata. /// /// /// PDF document stream. Must be readable and positioned at the beginning (Position = 0). /// Non-seekable streams are supported. Caller is responsible for disposal. /// /// PDF metadata (page count, size, version, attachments) /// /// Thrown when stream is empty, invalid, or not positioned at the beginning /// Task ValidateAsync(Stream pdfStream); /// /// Validates a PDF/A document and checks conformance level. /// /// /// PDF document stream. Must be readable and positioned at the beginning (Position = 0). /// Non-seekable streams are supported. Caller is responsible for disposal. /// /// PDF/A metadata including conformance level and validation errors/warnings /// /// Thrown when stream is empty, invalid, or not positioned at the beginning /// Task ValidatePdfAAsync(Stream pdfStream); /// /// Checks for embedded files (attachments) in a PDF document and returns detailed metadata. /// /// /// PDF document stream. Must be readable and positioned at the beginning (Position = 0). /// Non-seekable streams are supported. Caller is responsible for disposal. /// /// Attachment information (count, file names, MIME types, sizes) /// /// Thrown when stream is empty, invalid, or not positioned at the beginning /// Task CheckAttachmentsAsync(Stream pdfStream); /// /// Extracts all embedded files from a PDF document and returns them as a ZIP archive. /// /// /// PDF document stream. Must be readable and positioned at the beginning (Position = 0). /// Non-seekable streams are supported. Caller is responsible for disposal. /// /// ZIP archive containing all extracted attachments as byte array /// /// Thrown when stream is empty, invalid, or not positioned at the beginning /// /// /// Thrown when PDF contains no attachments /// Task ExtractAttachmentsAsync(Stream pdfStream); /// /// Merges multiple PDF documents into a single PDF. /// /// /// PDF streams to merge (minimum 2 required). Each stream must be readable and positioned /// at the beginning (Position = 0). Caller is responsible for disposal. /// /// /// Optional page ranges per PDF (null = all pages). Format: "1-3,5" means pages 1, 2, 3, and 5. /// If null or empty for a PDF, all pages are included. Array length must match pdfStreams length if provided. /// /// Merged PDF as byte array /// /// Thrown when fewer than 2 PDFs provided, any stream is empty/invalid/not at Position=0, /// or page range format is invalid /// Task MergePdfsAsync(IReadOnlyList pdfStreams, IReadOnlyList? pageRanges = null); /// /// Adds an annotation to a PDF document at the specified page and rectangle. /// /// /// PDF document stream. Must be readable and positioned at the beginning (Position = 0). /// Non-seekable streams are supported. Caller is responsible for disposal. /// /// Type of annotation to add (TextMarkup, FreeText, StickyNote, Circle, Square) /// Page number (1-based) where annotation should be added /// Annotation bounding rectangle (X1, Y1, X2, Y2) in PDF coordinates /// Annotation content/comment text (required for FreeText and StickyNote) /// Optional author name /// Optional annotation color in RGB format (hex string like "FF0000" for red) /// Text markup style (Highlight, Underline, Strikeout) - only for TextMarkup type /// Annotated PDF as byte array /// /// Thrown when stream is empty/invalid/not at Position=0, page number out of range, /// rectangle invalid, or content missing for types that require it /// Task AddAnnotationAsync( Stream pdfStream, Domain.Models.ValueObjects.AnnotationType annotationType, int pageNumber, (double X1, double Y1, double X2, double Y2) rectangle, string? content = null, string? author = null, string? color = null, Domain.Models.ValueObjects.TextMarkupStyle? textMarkupStyle = null); }