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) /// 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 /// Coordinate origin (BottomLeft = PDF native, TopLeft = UI-friendly). Default: BottomLeft /// 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, Domain.Models.ValueObjects.AnnotationOrigin origin = Domain.Models.ValueObjects.AnnotationOrigin.BottomLeft); /// /// Adds a stamp (text, image, or predefined) to specified pages of a PDF document. /// /// Input PDF stream (must support reading and seeking) /// Type of stamp (Text, Image, or Predefined) /// Target page numbers (1-based). Null = all pages. /// Stamp position (X, Y coordinates) /// Stamp size (Width, Height). Null = auto-size for images. /// Coordinate origin (BottomLeft or TopLeft) /// Text content (required for Text stamps) /// Font name (default: Arial) /// Font size in points (default: 12) /// Hex color without # (e.g., "FF0000" for red, default: "000000") /// Opacity 0.0 (transparent) to 1.0 (opaque, default: 0.5) /// Rotation angle in degrees 0-360 (default: 0) /// Foreground (on top) or Background (behind content) /// Image data (required for Image stamps, PNG/JPEG) /// Predefined stamp type (required for Predefined stamps) /// Stamped PDF as byte array /// Invalid parameters (missing text/image, invalid page numbers, invalid opacity/rotation) /// DevExpress processing error Task AddStampAsync( Stream pdfStream, Domain.Models.ValueObjects.StampType stampType, int[]? pageNumbers, (double X, double Y) position, (double Width, double Height)? size = null, Domain.Models.ValueObjects.AnnotationOrigin origin = Domain.Models.ValueObjects.AnnotationOrigin.BottomLeft, string? text = null, string? fontName = null, double? fontSize = null, string? color = null, double? opacity = null, double? rotation = null, Domain.Models.ValueObjects.StampPlacement placement = Domain.Models.ValueObjects.StampPlacement.Foreground, byte[]? imageBytes = null, Domain.Models.ValueObjects.PredefinedStampType? predefinedType = null); }