// Generated by alef. Do not edit by hand.

import 'dart:typed_data';

export 'kreuzberg_bridge_generated/lib.dart';
export 'traits.dart';
import 'kreuzberg_bridge_generated/lib.dart' as rust_bridge;
// ignore: duplicate_import
import 'kreuzberg_bridge_generated/lib.dart';

class KreuzbergBridge {
  /// Extract content from a byte array.
  ///
  /// This is the main entry point for in-memory extraction. It performs the following steps:
  /// 1. Validate MIME type
  /// 2. Handle legacy format conversion if needed
  /// 3. Select appropriate extractor from registry
  /// 4. Extract content
  /// 5. Run post-processing pipeline
  ///
  /// # Arguments
  ///
  /// * `content` - The byte array to extract
  /// * `mime_type` - MIME type of the content
  /// * `config` - Extraction configuration
  ///
  /// # Returns
  ///
  /// An `ExtractionResult` containing the extracted content and metadata.
  ///
  /// # Errors
  ///
  /// Returns `KreuzbergError::Validation` if MIME type is invalid.
  /// Returns `KreuzbergError::UnsupportedFormat` if MIME type is not supported.
  ///
  /// # Example
  ///
  /// ```rust,no_run
  /// use kreuzberg::core::extractor::extract_bytes;
  /// use kreuzberg::core::config::ExtractionConfig;
  ///
  /// let config = ExtractionConfig::default();
  /// let bytes = b"Hello, world!";
  /// let result = extract_bytes(bytes, "text/plain", &config).await?;
  /// println!("Content: {}", result.content);
  /// ```
  /// throws anyhow::Error on failure
  static Future<ExtractionResult> extractBytes(Uint8List content, String mimeType, [ExtractionConfig? config]) async {
    return await rust_bridge.extractBytes(content: content, mimeType: mimeType, config: config ?? ExtractionConfig(useCache: true, enableQualityProcessing: true, ocr: null, forceOcr: false, forceOcrPages: null, disableOcr: false, chunking: null, contentFilter: null, images: null, pdfOptions: null, tokenReduction: null, languageDetection: null, pages: null, keywords: null, postprocessor: null, htmlOptions: null, htmlOutput: null, extractionTimeoutSecs: null, maxConcurrentExtractions: null, resultFormat: ResultFormat.unified, securityLimits: null, maxEmbeddedFileBytes: 0, outputFormat: OutputFormat.plain(), layout: null, useLayoutForMarkdown: false, includeDocumentStructure: false, acceleration: null, cacheNamespace: null, cacheTtlSecs: null, email: null, concurrency: null, maxArchiveDepth: 0, treeSitter: null, structuredExtraction: null, cancelToken: null));
  }

  /// Extract content from a file.
  ///
  /// This is the main entry point for file-based extraction. It performs the following steps:
  /// 1. Check cache for existing result (if caching enabled)
  /// 2. Detect or validate MIME type
  /// 3. Select appropriate extractor from registry
  /// 4. Extract content
  /// 5. Run post-processing pipeline
  /// 6. Store result in cache (if caching enabled)
  ///
  /// # Arguments
  ///
  /// * `path` - Path to the file to extract
  /// * `mime_type` - Optional MIME type override. If None, will be auto-detected
  /// * `config` - Extraction configuration
  ///
  /// # Returns
  ///
  /// An `ExtractionResult` containing the extracted content and metadata.
  ///
  /// # Errors
  ///
  /// Returns `KreuzbergError::Io` if the file doesn't exist (NotFound) or for other file I/O errors.
  /// Returns `KreuzbergError::UnsupportedFormat` if MIME type is not supported.
  ///
  /// # Example
  ///
  /// ```rust,no_run
  /// use kreuzberg::core::extractor::extract_file;
  /// use kreuzberg::core::config::ExtractionConfig;
  ///
  /// let config = ExtractionConfig::default();
  /// let result = extract_file("document.pdf", None, &config).await?;
  /// println!("Content: {}", result.content);
  /// ```
  /// throws anyhow::Error on failure
  static Future<ExtractionResult> extractFile(String path, String? mimeType, [ExtractionConfig? config]) async {
    return await rust_bridge.extractFile(path: path, mimeType: mimeType, config: config ?? ExtractionConfig(useCache: true, enableQualityProcessing: true, ocr: null, forceOcr: false, forceOcrPages: null, disableOcr: false, chunking: null, contentFilter: null, images: null, pdfOptions: null, tokenReduction: null, languageDetection: null, pages: null, keywords: null, postprocessor: null, htmlOptions: null, htmlOutput: null, extractionTimeoutSecs: null, maxConcurrentExtractions: null, resultFormat: ResultFormat.unified, securityLimits: null, maxEmbeddedFileBytes: 0, outputFormat: OutputFormat.plain(), layout: null, useLayoutForMarkdown: false, includeDocumentStructure: false, acceleration: null, cacheNamespace: null, cacheTtlSecs: null, email: null, concurrency: null, maxArchiveDepth: 0, treeSitter: null, structuredExtraction: null, cancelToken: null));
  }

  /// Synchronous wrapper for `extract_file`.
  ///
  /// This is a convenience function that blocks the current thread until extraction completes.
  /// For async code, use `extract_file` directly.
  ///
  /// Uses the global Tokio runtime for 100x+ performance improvement over creating
  /// a new runtime per call. Always uses the global runtime to avoid nested runtime issues.
  ///
  /// This function is only available with the `tokio-runtime` feature. For WASM targets,
  /// use a truly synchronous extraction approach instead.
  ///
  /// # Example
  ///
  /// ```rust,no_run
  /// use kreuzberg::core::extractor::extract_file_sync;
  /// use kreuzberg::core::config::ExtractionConfig;
  ///
  /// let config = ExtractionConfig::default();
  /// let result = extract_file_sync("document.pdf", None, &config)?;
  /// println!("Content: {}", result.content);
  /// ```
  /// throws anyhow::Error on failure
  static Future<ExtractionResult> extractFileSync(String path, String? mimeType, [ExtractionConfig? config]) async {
    return await rust_bridge.extractFileSync(path: path, mimeType: mimeType, config: config ?? ExtractionConfig(useCache: true, enableQualityProcessing: true, ocr: null, forceOcr: false, forceOcrPages: null, disableOcr: false, chunking: null, contentFilter: null, images: null, pdfOptions: null, tokenReduction: null, languageDetection: null, pages: null, keywords: null, postprocessor: null, htmlOptions: null, htmlOutput: null, extractionTimeoutSecs: null, maxConcurrentExtractions: null, resultFormat: ResultFormat.unified, securityLimits: null, maxEmbeddedFileBytes: 0, outputFormat: OutputFormat.plain(), layout: null, useLayoutForMarkdown: false, includeDocumentStructure: false, acceleration: null, cacheNamespace: null, cacheTtlSecs: null, email: null, concurrency: null, maxArchiveDepth: 0, treeSitter: null, structuredExtraction: null, cancelToken: null));
  }

  /// Synchronous wrapper for `extract_bytes`.
  ///
  /// Uses the global Tokio runtime for 100x+ performance improvement over creating
  /// a new runtime per call.
  ///
  /// With the `tokio-runtime` feature, this blocks the current thread using the global
  /// Tokio runtime. Without it (WASM), this calls a truly synchronous implementation.
  ///
  /// # Example
  ///
  /// ```rust,no_run
  /// use kreuzberg::core::extractor::extract_bytes_sync;
  /// use kreuzberg::core::config::ExtractionConfig;
  ///
  /// let config = ExtractionConfig::default();
  /// let bytes = b"Hello, world!";
  /// let result = extract_bytes_sync(bytes, "text/plain", &config)?;
  /// println!("Content: {}", result.content);
  /// ```
  /// throws anyhow::Error on failure
  static Future<ExtractionResult> extractBytesSync(Uint8List content, String mimeType, [ExtractionConfig? config]) async {
    return await rust_bridge.extractBytesSync(content: content, mimeType: mimeType, config: config ?? ExtractionConfig(useCache: true, enableQualityProcessing: true, ocr: null, forceOcr: false, forceOcrPages: null, disableOcr: false, chunking: null, contentFilter: null, images: null, pdfOptions: null, tokenReduction: null, languageDetection: null, pages: null, keywords: null, postprocessor: null, htmlOptions: null, htmlOutput: null, extractionTimeoutSecs: 0, maxConcurrentExtractions: null, resultFormat: ResultFormat.unified, securityLimits: null, maxEmbeddedFileBytes: 0, outputFormat: OutputFormat.plain(), layout: null, useLayoutForMarkdown: false, includeDocumentStructure: false, acceleration: null, cacheNamespace: null, cacheTtlSecs: null, email: null, concurrency: null, maxArchiveDepth: 0, treeSitter: null, structuredExtraction: null, cancelToken: null));
  }

  /// Synchronous wrapper for `batch_extract_files`.
  ///
  /// Uses the global Tokio runtime for optimal performance.
  /// Only available with `tokio-runtime` (WASM has no filesystem).
  ///
  /// # Example
  ///
  /// ```rust,no_run
  /// use kreuzberg::core::extractor::batch_extract_files_sync;
  /// use kreuzberg::core::config::{ExtractionConfig, BatchFileItem, FileExtractionConfig};
  ///
  /// let config = ExtractionConfig::default();
  /// let items = vec![
  ///     BatchFileItem {
  ///         path: "doc1.pdf".into(),
  ///         config: Some(FileExtractionConfig { force_ocr: Some(true), ..Default::default() }),
  ///     },
  ///     BatchFileItem { path: "doc2.pdf".into(), config: None },
  /// ];
  /// let results = batch_extract_files_sync(items, &config)?;
  /// ```
  /// throws anyhow::Error on failure
  static Future<List<ExtractionResult>> batchExtractFilesSync(List<BatchFileItem> items, [ExtractionConfig? config]) async {
    return await rust_bridge.batchExtractFilesSync(items: items, config: config ?? ExtractionConfig(useCache: true, enableQualityProcessing: true, ocr: null, forceOcr: false, forceOcrPages: null, disableOcr: false, chunking: null, contentFilter: null, images: null, pdfOptions: null, tokenReduction: null, languageDetection: null, pages: null, keywords: null, postprocessor: null, htmlOptions: null, htmlOutput: null, extractionTimeoutSecs: null, maxConcurrentExtractions: null, resultFormat: ResultFormat.unified, securityLimits: null, maxEmbeddedFileBytes: 0, outputFormat: OutputFormat.plain(), layout: null, useLayoutForMarkdown: false, includeDocumentStructure: false, acceleration: null, cacheNamespace: null, cacheTtlSecs: null, email: null, concurrency: null, maxArchiveDepth: 0, treeSitter: null, structuredExtraction: null, cancelToken: null));
  }

  /// Synchronous wrapper for `batch_extract_bytes`.
  ///
  /// Uses the global Tokio runtime for optimal performance.
  /// With the `tokio-runtime` feature, this blocks the current thread using the global
  /// Tokio runtime. Without it (WASM), this calls a truly synchronous implementation
  /// that iterates through items and calls `extract_bytes_sync()`.
  ///
  /// # Example
  ///
  /// ```rust,no_run
  /// use kreuzberg::core::extractor::batch_extract_bytes_sync;
  /// use kreuzberg::core::config::{ExtractionConfig, BatchBytesItem, FileExtractionConfig};
  ///
  /// let config = ExtractionConfig::default();
  /// let items = vec![
  ///     BatchBytesItem { content: b"content".to_vec(), mime_type: "text/plain".to_string(), config: None },
  ///     BatchBytesItem {
  ///         content: b"other".to_vec(),
  ///         mime_type: "text/plain".to_string(),
  ///         config: Some(FileExtractionConfig { force_ocr: Some(true), ..Default::default() }),
  ///     },
  /// ];
  /// let results = batch_extract_bytes_sync(items, &config)?;
  /// ```
  /// throws anyhow::Error on failure
  static Future<List<ExtractionResult>> batchExtractBytesSync(List<BatchBytesItem> items, [ExtractionConfig? config]) async {
    return await rust_bridge.batchExtractBytesSync(items: items, config: config ?? ExtractionConfig(useCache: true, enableQualityProcessing: true, ocr: null, forceOcr: false, forceOcrPages: null, disableOcr: false, chunking: null, contentFilter: null, images: null, pdfOptions: null, tokenReduction: null, languageDetection: null, pages: null, keywords: null, postprocessor: null, htmlOptions: null, htmlOutput: null, extractionTimeoutSecs: null, maxConcurrentExtractions: null, resultFormat: ResultFormat.unified, securityLimits: null, maxEmbeddedFileBytes: 0, outputFormat: OutputFormat.plain(), layout: null, useLayoutForMarkdown: false, includeDocumentStructure: false, acceleration: null, cacheNamespace: null, cacheTtlSecs: null, email: null, concurrency: null, maxArchiveDepth: 0, treeSitter: null, structuredExtraction: null, cancelToken: null));
  }

  /// Extract content from multiple files concurrently.
  ///
  /// This function processes multiple files in parallel, automatically managing
  /// concurrency to prevent resource exhaustion. The concurrency limit can be
  /// configured via `ExtractionConfig::max_concurrent_extractions` or defaults
  /// to `(num_cpus * 1.5).ceil()`.
  ///
  /// Each file can optionally specify a [`FileExtractionConfig`] that overrides specific
  /// fields from the batch-level `config`. Pass `None` for a file to use the batch defaults.
  /// Batch-level settings like `max_concurrent_extractions` and `use_cache` are always
  /// taken from the batch-level `config`.
  ///
  /// # Arguments
  ///
  /// * `items` - Vector of `BatchFileItem` structs, each containing a path and optional
  ///   per-file configuration overrides.
  /// * `config` - Batch-level extraction configuration (provides defaults and batch settings)
  ///
  /// # Returns
  ///
  /// A vector of `ExtractionResult` in the same order as the input items.
  ///
  /// # Errors
  ///
  /// Individual file errors are captured in the result metadata. System errors
  /// (IO, RuntimeError equivalents) will bubble up and fail the entire batch.
  ///
  /// # Examples
  ///
  /// Simple usage with no per-file overrides:
  ///
  /// ```rust,no_run
  /// use kreuzberg::core::extractor::batch_extract_files;
  /// use kreuzberg::core::config::{ExtractionConfig, BatchFileItem};
  /// use std::path::PathBuf;
  ///
  /// let config = ExtractionConfig::default();
  /// let items = vec![
  ///     BatchFileItem { path: "doc1.pdf".into(), config: None },
  ///     BatchFileItem { path: "doc2.pdf".into(), config: None },
  /// ];
  /// let results = batch_extract_files(items, &config).await?;
  /// println!("Processed {} files", results.len());
  /// ```
  ///
  /// Per-file configuration overrides:
  ///
  /// ```rust,no_run
  /// use kreuzberg::core::extractor::batch_extract_files;
  /// use kreuzberg::core::config::{ExtractionConfig, BatchFileItem, FileExtractionConfig};
  /// use std::path::PathBuf;
  ///
  /// let config = ExtractionConfig::default();
  /// let items = vec![
  ///     BatchFileItem {
  ///         path: "scan.pdf".into(),
  ///         config: Some(FileExtractionConfig { force_ocr: Some(true), ..Default::default() }),
  ///     },
  ///     BatchFileItem { path: "notes.txt".into(), config: None },
  /// ];
  /// let results = batch_extract_files(items, &config).await?;
  /// ```
  /// throws anyhow::Error on failure
  static Future<List<ExtractionResult>> batchExtractFiles(List<BatchFileItem> items, [ExtractionConfig? config]) async {
    return await rust_bridge.batchExtractFiles(items: items, config: config ?? ExtractionConfig(useCache: true, enableQualityProcessing: true, ocr: null, forceOcr: false, forceOcrPages: null, disableOcr: false, chunking: null, contentFilter: null, images: null, pdfOptions: null, tokenReduction: null, languageDetection: null, pages: null, keywords: null, postprocessor: null, htmlOptions: null, htmlOutput: null, extractionTimeoutSecs: null, maxConcurrentExtractions: null, resultFormat: ResultFormat.unified, securityLimits: null, maxEmbeddedFileBytes: 0, outputFormat: OutputFormat.plain(), layout: null, useLayoutForMarkdown: false, includeDocumentStructure: false, acceleration: null, cacheNamespace: null, cacheTtlSecs: null, email: null, concurrency: null, maxArchiveDepth: 0, treeSitter: null, structuredExtraction: null, cancelToken: null));
  }

  /// Extract content from multiple byte arrays concurrently.
  ///
  /// This function processes multiple byte arrays in parallel, automatically managing
  /// concurrency to prevent resource exhaustion. The concurrency limit can be
  /// configured via `ExtractionConfig::max_concurrent_extractions` or defaults
  /// to `(num_cpus * 1.5).ceil()`.
  ///
  /// Each item can optionally specify a [`FileExtractionConfig`] that overrides specific
  /// fields from the batch-level `config`. Pass `None` as the config to use
  /// the batch-level defaults for that item.
  ///
  /// # Arguments
  ///
  /// * `items` - Vector of `BatchBytesItem` structs, each containing content bytes,
  ///   MIME type, and optional per-item configuration overrides.
  /// * `config` - Batch-level extraction configuration
  ///
  /// # Returns
  ///
  /// A vector of `ExtractionResult` in the same order as the input items.
  ///
  /// # Examples
  ///
  /// Simple usage with no per-item overrides:
  ///
  /// ```rust,no_run
  /// use kreuzberg::core::extractor::batch_extract_bytes;
  /// use kreuzberg::core::config::{ExtractionConfig, BatchBytesItem};
  ///
  /// let config = ExtractionConfig::default();
  /// let items = vec![
  ///     BatchBytesItem { content: b"content 1".to_vec(), mime_type: "text/plain".to_string(), config: None },
  ///     BatchBytesItem { content: b"content 2".to_vec(), mime_type: "text/plain".to_string(), config: None },
  /// ];
  /// let results = batch_extract_bytes(items, &config).await?;
  /// println!("Processed {} items", results.len());
  /// ```
  ///
  /// Per-item configuration overrides:
  ///
  /// ```rust,no_run
  /// use kreuzberg::core::extractor::batch_extract_bytes;
  /// use kreuzberg::core::config::{ExtractionConfig, BatchBytesItem, FileExtractionConfig};
  ///
  /// let config = ExtractionConfig::default();
  /// let items = vec![
  ///     BatchBytesItem { content: b"content".to_vec(), mime_type: "text/plain".to_string(), config: None },
  ///     BatchBytesItem {
  ///         content: b"<html>test</html>".to_vec(),
  ///         mime_type: "text/html".to_string(),
  ///         config: Some(FileExtractionConfig { force_ocr: Some(true), ..Default::default() }),
  ///     },
  /// ];
  /// let results = batch_extract_bytes(items, &config).await?;
  /// ```
  /// throws anyhow::Error on failure
  static Future<List<ExtractionResult>> batchExtractBytes(List<BatchBytesItem> items, [ExtractionConfig? config]) async {
    return await rust_bridge.batchExtractBytes(items: items, config: config ?? ExtractionConfig(useCache: true, enableQualityProcessing: true, ocr: null, forceOcr: false, forceOcrPages: null, disableOcr: false, chunking: null, contentFilter: null, images: null, pdfOptions: null, tokenReduction: null, languageDetection: null, pages: null, keywords: null, postprocessor: null, htmlOptions: null, htmlOutput: null, extractionTimeoutSecs: null, maxConcurrentExtractions: null, resultFormat: ResultFormat.unified, securityLimits: null, maxEmbeddedFileBytes: 0, outputFormat: OutputFormat.plain(), layout: null, useLayoutForMarkdown: false, includeDocumentStructure: false, acceleration: null, cacheNamespace: null, cacheTtlSecs: null, email: null, concurrency: null, maxArchiveDepth: 0, treeSitter: null, structuredExtraction: null, cancelToken: null));
  }

  /// Detect MIME type from raw file bytes.
  ///
  /// Uses magic byte signatures to detect file type from content.
  /// Falls back to `infer` crate for comprehensive detection.
  ///
  /// For ZIP-based files, inspects contents to distinguish Office Open XML
  /// formats (DOCX, XLSX, PPTX) from plain ZIP archives.
  ///
  /// # Arguments
  ///
  /// * `content` - Raw file bytes
  ///
  /// # Returns
  ///
  /// The detected MIME type string.
  ///
  /// # Errors
  ///
  /// Returns `KreuzbergError::UnsupportedFormat` if MIME type cannot be determined.
  /// throws anyhow::Error on failure
  static Future<String> detectMimeTypeFromBytes(Uint8List content) async {
    return await rust_bridge.detectMimeTypeFromBytes(content: content);
  }

  /// Get file extensions for a given MIME type.
  ///
  /// Returns all known file extensions that map to the specified MIME type.
  ///
  /// # Arguments
  ///
  /// * `mime_type` - The MIME type to look up
  ///
  /// # Returns
  ///
  /// A vector of file extensions (without leading dot) for the MIME type.
  ///
  /// # Example
  ///
  /// ```
  /// use kreuzberg::core::mime::get_extensions_for_mime;
  ///
  /// let extensions = get_extensions_for_mime("application/pdf").unwrap();
  /// assert_eq!(extensions, vec!["pdf"]);
  ///
  /// let doc_extensions = get_extensions_for_mime("application/vnd.openxmlformats-officedocument.wordprocessingml.document").unwrap();
  /// assert!(doc_extensions.contains(&"docx".to_string()));
  /// ```
  /// throws anyhow::Error on failure
  static Future<List<String>> getExtensionsForMime(String mimeType) async {
    return await rust_bridge.getExtensionsForMime(mimeType: mimeType);
  }

  /// List the names of all registered embedding backends.
  ///
  /// Used by `kreuzberg-cli`, the api/mcp endpoints, and generated language
  /// bindings.
  /// throws anyhow::Error on failure
  static Future<List<String>> listEmbeddingBackends() async {
    return await rust_bridge.listEmbeddingBackends();
  }

  /// List names of all registered document extractors.
  /// throws anyhow::Error on failure
  static Future<List<String>> listDocumentExtractors() async {
    return await rust_bridge.listDocumentExtractors();
  }

  /// List all registered OCR backends.
  ///
  /// Returns the names of all OCR backends currently registered in the global registry.
  ///
  /// # Returns
  ///
  /// A vector of OCR backend names.
  ///
  /// # Example
  ///
  /// ```rust
  /// use kreuzberg::plugins::list_ocr_backends;
  ///
  /// let backends = list_ocr_backends()?;
  /// for name in backends {
  ///     println!("Registered OCR backend: {}", name);
  /// }
  /// ```
  /// throws anyhow::Error on failure
  static Future<List<String>> listOcrBackends() async {
    return await rust_bridge.listOcrBackends();
  }

  /// List all registered post-processor names.
  ///
  /// Returns a vector of all post-processor names currently registered in the
  /// global registry.
  ///
  /// # Returns
  ///
  /// - `Ok(Vec<String>)` - Vector of post-processor names
  /// - `Err(...)` if the registry lock is poisoned
  ///
  /// # Example
  ///
  /// ```rust
  /// use kreuzberg::plugins::list_post_processors;
  ///
  /// let processors = list_post_processors()?;
  /// for name in processors {
  ///     println!("Registered post-processor: {}", name);
  /// }
  /// ```
  /// throws anyhow::Error on failure
  static Future<List<String>> listPostProcessors() async {
    return await rust_bridge.listPostProcessors();
  }

  /// List names of all registered renderers.
  ///
  /// # Errors
  ///
  /// Returns an error if the registry lock is poisoned.
  /// throws anyhow::Error on failure
  static Future<List<String>> listRenderers() async {
    return await rust_bridge.listRenderers();
  }

  /// List names of all registered validators.
  /// throws anyhow::Error on failure
  static Future<List<String>> listValidators() async {
    return await rust_bridge.listValidators();
  }

  /// Compare two extraction results and return a structured diff.
  ///
  /// The comparison is purely structural — no I/O, no side effects. All fields
  /// of [`ExtractionDiff`] are populated according to the provided [`DiffOptions`].
  ///
  /// # Arguments
  ///
  /// * `a` — the "before" extraction result
  /// * `b` — the "after" extraction result
  /// * `opts` — controls which sections are compared and optional truncation
  ///
  /// # Example
  ///
  /// ```rust,no_run
  /// use kreuzberg::{ExtractionResult, diff::{compare, DiffOptions}};
  ///
  /// let mut a = ExtractionResult::default();
  /// let mut b = ExtractionResult::default();
  /// a.content = "Hello world".to_string();
  /// b.content = "Hello Rust".to_string();
  ///
  /// let diff = compare(&a, &b, &DiffOptions::default());
  /// assert_eq!(diff.content_diff.len(), 1);
  /// ```
  static Future<ExtractionDiff> compare(ExtractionResult a, ExtractionResult b, DiffOptions opts) async {
    return await rust_bridge.compare(a: a, b: b, opts: opts);
  }

  /// Generate embeddings asynchronously for a list of text strings.
  ///
  /// This is the async counterpart to [`embed_texts`]. It offloads the blocking
  /// ONNX inference work to a dedicated blocking thread pool via Tokio's
  /// `spawn_blocking`, keeping the async executor free.
  ///
  /// Returns one embedding vector per input text in the same order.
  ///
  /// # Arguments
  ///
  /// * `texts` - Vec of strings to embed (owned, sent to blocking thread)
  /// * `config` - Embedding configuration specifying model, batch size, and normalization
  ///
  /// # Errors
  ///
  /// - `KreuzbergError::MissingDependency` if ONNX Runtime is not installed
  /// - `KreuzbergError::Embedding` if the preset name is unknown, model download fails,
  ///   or the blocking inference task panics
  ///
  /// # Example
  ///
  /// ```rust,ignore
  /// use kreuzberg::{embed_texts_async, EmbeddingConfig};
  ///
  /// let embeddings = embed_texts_async(
  ///     vec!["Hello!".to_string()],
  ///     &EmbeddingConfig::default(),
  /// ).await?;
  /// ```
  /// throws anyhow::Error on failure
  static Future<List<Float64List>> embedTextsAsync(List<String> texts, EmbeddingConfig config) async {
    return await rust_bridge.embedTextsAsync(texts: texts, config: config);
  }

  /// Render a single PDF page to PNG bytes.
  ///
  /// Returns raw PNG-encoded bytes for the specified page at the given DPI.
  /// Uses pdf_oxide with tiny-skia for pure-Rust rendering.
  ///
  /// # Arguments
  ///
  /// * `pdf_bytes` - Raw PDF file bytes
  /// * `page_index` - Zero-based page index
  /// * `dpi` - Resolution in dots per inch (default: 150)
  /// * `password` - Optional password for encrypted PDFs
  ///
  /// # Errors
  ///
  /// Returns `KreuzbergError::Parsing` if the PDF cannot be opened, authenticated,
  /// or rendered, or if `page_index` is out of range.
  /// throws anyhow::Error on failure
  static Future<Uint8List> renderPdfPageToPng(Uint8List pdfBytes, int pageIndex, {int? dpi, String? password}) async {
    return await rust_bridge.renderPdfPageToPng(pdfBytes: pdfBytes, pageIndex: pageIndex, dpi: dpi, password: password);
  }

  /// Detect the MIME type of a file at the given path.
  ///
  /// Uses the file extension and optionally the file content to determine the MIME type.
  /// Set `check_exists` to `true` to verify the file exists before detection.
  /// throws anyhow::Error on failure
  static Future<String> detectMimeType(String path, bool checkExists) async {
    return await rust_bridge.detectMimeType(path: path, checkExists: checkExists);
  }

  /// Embed a list of texts using the configured embedding model.
  ///
  /// Returns a 2D vector where each inner vector is the embedding for the corresponding text.
  /// throws anyhow::Error on failure
  static Future<List<Float64List>> embedTexts(List<String> texts, EmbeddingConfig config) async {
    return await rust_bridge.embedTexts(texts: texts, config: config);
  }

  /// Get an embedding preset by name.
  ///
  /// Returns `None` if no preset with the given name exists. Returns an owned
  /// clone so the value is safe to pass across FFI boundaries.
  static Future<EmbeddingPreset?> getEmbeddingPreset(String name) async {
    return await rust_bridge.getEmbeddingPreset(name: name);
  }

  /// List the names of all available embedding presets.
  ///
  /// Returns owned `String`s so the values are safe to pass across FFI boundaries.
  static Future<List<String>> listEmbeddingPresets() async {
    return await rust_bridge.listEmbeddingPresets();
  }

  /// Register a Dart implementation of [OcrBackend] with the plugin registry.
  static Future<void> registerOcrBackend(OcrBackendDartImpl impl) async {
    await rust_bridge.registerOcrBackend(impl: impl);
  }
  /// Unregister a previously-registered [OcrBackend] plugin by name.
  static Future<void> unregisterOcrBackend(String name) async {
    await rust_bridge.unregisterOcrBackend(name: name);
  }
  /// Clear all registered [OcrBackend] plugins from the registry.
  static Future<void> clearOcrBackends() async {
    await rust_bridge.clearOcrBackends();
  }
  /// Register a Dart implementation of [PostProcessor] with the plugin registry.
  static Future<void> registerPostProcessor(PostProcessorDartImpl impl) async {
    await rust_bridge.registerPostProcessor(impl: impl);
  }
  /// Unregister a previously-registered [PostProcessor] plugin by name.
  static Future<void> unregisterPostProcessor(String name) async {
    await rust_bridge.unregisterPostProcessor(name: name);
  }
  /// Clear all registered [PostProcessor] plugins from the registry.
  static Future<void> clearPostProcessors() async {
    await rust_bridge.clearPostProcessors();
  }
  /// Register a Dart implementation of [Validator] with the plugin registry.
  static Future<void> registerValidator(ValidatorDartImpl impl) async {
    await rust_bridge.registerValidator(impl: impl);
  }
  /// Unregister a previously-registered [Validator] plugin by name.
  static Future<void> unregisterValidator(String name) async {
    await rust_bridge.unregisterValidator(name: name);
  }
  /// Clear all registered [Validator] plugins from the registry.
  static Future<void> clearValidators() async {
    await rust_bridge.clearValidators();
  }
  /// Register a Dart implementation of [EmbeddingBackend] with the plugin registry.
  static Future<void> registerEmbeddingBackend(EmbeddingBackendDartImpl impl) async {
    await rust_bridge.registerEmbeddingBackend(impl: impl);
  }
  /// Unregister a previously-registered [EmbeddingBackend] plugin by name.
  static Future<void> unregisterEmbeddingBackend(String name) async {
    await rust_bridge.unregisterEmbeddingBackend(name: name);
  }
  /// Clear all registered [EmbeddingBackend] plugins from the registry.
  static Future<void> clearEmbeddingBackends() async {
    await rust_bridge.clearEmbeddingBackends();
  }
  /// Register a Dart implementation of [DocumentExtractor] with the plugin registry.
  static Future<void> registerDocumentExtractor(DocumentExtractorDartImpl impl) async {
    await rust_bridge.registerDocumentExtractor(impl: impl);
  }
  /// Unregister a previously-registered [DocumentExtractor] plugin by name.
  static Future<void> unregisterDocumentExtractor(String name) async {
    await rust_bridge.unregisterDocumentExtractor(name: name);
  }
  /// Clear all registered [DocumentExtractor] plugins from the registry.
  static Future<void> clearDocumentExtractors() async {
    await rust_bridge.clearDocumentExtractors();
  }
  /// Register a Dart implementation of [Renderer] with the plugin registry.
  static Future<void> registerRenderer(RendererDartImpl impl) async {
    await rust_bridge.registerRenderer(impl: impl);
  }
  /// Unregister a previously-registered [Renderer] plugin by name.
  static Future<void> unregisterRenderer(String name) async {
    await rust_bridge.unregisterRenderer(name: name);
  }
  /// Clear all registered [Renderer] plugins from the registry.
  static Future<void> clearRenderers() async {
    await rust_bridge.clearRenderers();
  }
}
