/**
 * HTTP Upload Handler for OCR Provenance MCP System
 *
 * Handles multipart file uploads via busboy, stages files to /data/staged/,
 * validates them (filename, extension, magic bytes, size), computes SHA-256
 * hashes, and creates document + provenance records in the database.
 *
 * CRITICAL: NEVER use console.log() — stdout is JSON-RPC. Use console.error() for ALL logging.
 * CRITICAL: NEVER fallback/degrade in catch blocks — throw with context.
 *
 * @module services/upload/handler
 */
import { IncomingMessage, ServerResponse } from 'http';
import type { ProvenanceRecord } from '../../models/provenance.js';
import type { Document } from '../../models/document.js';
/** Result for a successfully uploaded file */
export interface FileResult {
    /** Sanitized filename used on disk */
    original_name: string;
    /** Raw untouched filename from the upload — preserved for provenance */
    raw_original_name: string;
    staged_path: string;
    document_id: string;
    file_hash: string;
    file_size: number;
    status: 'pending';
}
/** Result for a skipped (duplicate) file */
export interface SkipResult {
    original_name: string;
    reason: string;
    existing_document_id: string;
}
/** Aggregate upload response */
export interface UploadResult {
    uploaded: number;
    skipped: number;
    failed: number;
    total_bytes: number;
    database: string;
    auto_process: boolean;
    files: FileResult[];
    skipped_files: SkipResult[];
}
/** Result from cleanup operations */
export interface CleanupResult {
    deleted_count: number;
    freed_bytes: number;
    freed_human: string;
}
/**
 * Interface for database operations required by the upload handler.
 * Matches the methods available on DatabaseService.
 */
interface UploadDatabaseConnection {
    getDocumentByHash(fileHash: string): Document | null;
    insertDocument(doc: Omit<Document, 'created_at'>): string;
    insertProvenance(record: ProvenanceRecord): string;
}
/**
 * Sanitize a filename to prevent path traversal and injection attacks.
 *
 * - Rejects null bytes (throws ValidationError)
 * - Strips directory components via path.basename (handles both / and \)
 * - Rejects empty/whitespace-only results (throws ValidationError)
 * - Truncates to 255 characters
 * - Replaces control characters (0x00-0x1F except tab/newline) with underscore
 *
 * @param name - Raw filename from upload
 * @returns Sanitized filename (basename only)
 * @throws ValidationError on null bytes, empty result
 */
export declare function sanitizeFilename(name: string): string;
/**
 * Validate file content by checking magic bytes against expected extension.
 *
 * - For text types (txt, csv, md): always returns true (no magic bytes)
 * - For PDF: checks for %PDF header
 * - For PNG: checks for \x89PNG header
 * - For JPEG: checks for \xFF\xD8\xFF header
 * - For DOCX/XLSX/PPTX: checks for PK\x03\x04 (ZIP/Office) header
 * - For other types: returns true (allow through)
 * - For empty buffer: returns false
 * - Always rejects ELF (\x7FELF) and MZ (Windows exe) headers
 *
 * @param buffer - First bytes of the file
 * @param extension - File extension (without dot, lowercase)
 * @returns true if magic bytes match (or type has no magic check), false otherwise
 */
export declare function validateMagicBytes(buffer: Buffer, extension: string): boolean;
/**
 * Detect the actual file format from magic bytes, regardless of extension.
 * Returns a human-readable format name and suggested extension.
 * Returns null if format cannot be determined.
 */
export declare function detectFormatFromMagicBytes(buffer: Buffer): {
    format: string;
    suggestedExt: string;
} | null;
/**
 * Check whether a file extension is a valid upload type.
 *
 * @param ext - File extension without dot (case-insensitive)
 * @returns true if the extension is in SUPPORTED_FILE_TYPES
 */
export declare function isValidUploadType(ext: string): boolean;
/**
 * Handle a multipart file upload HTTP request.
 *
 * Parses multipart/form-data via busboy, stages files to /data/staged/{batchUuid}/,
 * validates them, computes SHA-256 hashes during streaming, checks for duplicates,
 * and creates document + provenance records in the database.
 *
 * @param req - Node.js HTTP IncomingMessage
 * @param res - Node.js HTTP ServerResponse
 * @param getDatabaseConnection - Callback returning a database connection
 * @param databaseName - Optional target database name
 */
export declare function handleUpload(req: IncomingMessage, res: ServerResponse, getDatabaseConnection: (dbName?: string) => UploadDatabaseConnection, databaseName?: string): Promise<void>;
/**
 * Clean up staged files older than a specified threshold.
 *
 * @param olderThanHours - Delete batch directories older than this many hours (default: 24)
 * @param deleteAll - If true, delete all staged files regardless of age (default: false)
 * @returns CleanupResult with count, bytes freed, and human-readable size
 */
export declare function cleanupStagedFiles(olderThanHours?: number, deleteAll?: boolean): CleanupResult;
/**
 * Enforce the staging area quota.
 *
 * If /data/staged exceeds STAGED_MAX_SIZE (10 GB), delete the oldest batch
 * directories until total is below 80% of the limit (8 GB).
 *
 * Logs cleanup actions via console.error.
 */
export declare function enforceStageQuota(): void;
export {};
//# sourceMappingURL=handler.d.ts.map