//! `SqPack` archive reader and writer for FFXIV.
//!
//! Opens the paired `.index`/`.index2` and `.dat` files that make up an
//! FFXIV installation — read any game asset by its in-engine path, verify
//! install integrity, decode structured data and asset formats, or write
//! new files via append or full repack. The library never touches the
//! network.
//!
//! # Quick start
//!
//! ```no_run
//! use sqpack_rs::SqPack;
//!
//! let sq = SqPack::open("/path/to/ffxiv/game")?;
//! let bytes = sq.read_file("exd/root.exl")?;
//! println!("exl is {} bytes", bytes.len());
//! # Ok::<(), sqpack_rs::Error>(())
//! ```
//!
//! # Module overview
//!
//! | Module | Purpose |
//! |---|---|
//! | [`sqpack`] | High-level [`SqPack`] entry point — open install, read files |
//! | [`dat`] | `.dat` reader, block decompression, [`SqPackPayload`] dispatch |
//! | [`index`] | `.index` (v1) reader — 64-bit composite-key hash table |
//! | [`index2`] | `.index2` (v2) reader — 32-bit full-path hash table |
//! | [`hash`] | CRC32 path-hashing with FFXIV's polynomial |
//! | [`route`] | Game-path → [`Category`] / expansion / chunk routing |
//! | [`header`] | On-disk `SqPack` header types |
//! | [`error`] | [`Error`] and [`Result`] |
//! | [`vfs`] | [`Vfs`] trait + [`StdFs`] filesystem abstraction |
//! | [`mmap_fs`] | [`MmapFs`] — memory-mapped I/O backend (feature `mmap`) |
//! | [`cancel`] | [`CancelToken`] for cooperative cancellation |
//! | [`observer`] | Observer traits for scan/verify progress reporting |
//! | [`verify`] | Archive integrity verification and manifest building |
//! | [`write`] | [`SqPackAppender`] / [`SqPackRepacker`] — write support |
//! | [`excel`] | EXD/EXH/EXL Excel data-sheet parsing |
//! | [`tex`] | TEX texture decoder |
//! | [`mdl`] | MDL model parser |
//! | [`scd`] | SCD audio decoder |
//! | [`sklb`] | SKLB skeleton binary parser |
//! | [`pap`] | PAP animation file parser |
//! | [`phyb`] | PHYB physics binary parser |
//! | [`tmb`] | TMB timeline binary parser |
//! | [`eid`] | EID entity-ID table parser |
//!
//! # Tracing
//!
//! The library emits structured [`tracing`](https://docs.rs/tracing) spans
//! and events. Span and field names at the `info` and `debug` levels are
//! SemVer-stable; `trace`-level names are best-effort. No subscriber is
//! configured — that is the consumer's responsibility. See the
//! [`tracing_schema`] module for the canonical name constants.
//!
//! # Async usage
//!
//! All entry points are synchronous. Async consumers should run calls on
//! a blocking-pool thread (e.g. `tokio::task::spawn_blocking`). See the
//! [`cancel`] and [`observer`] modules for cooperative cancellation and
//! progress reporting across thread boundaries.

#![allow(missing_docs)]
#![cfg_attr(docsrs, feature(doc_cfg))]

#[cfg(not(any(feature = "rust-backend", feature = "zlib-rs", feature = "zlib-ng")))]
compile_error!(
    "sqpack-rs requires a flate2 backend. Enable exactly one of the features \
     `rust-backend` (default, pure-Rust via miniz_oxide), `zlib-rs` (pure-Rust \
     via zlib-rs), or `zlib-ng` (C via zlib-ng). If you set \
     `default-features = false`, re-enable a backend explicitly, e.g. \
     `features = [\"rust-backend\"]`."
);

#[cfg(feature = "block-cache")]
pub mod block_cache;
pub mod cancel;
pub mod dat;
pub mod eid;
pub mod error;
pub mod excel;
pub mod hash;
pub mod header;
pub mod index;
pub mod index2;
pub mod mdl;
#[cfg(feature = "mmap")]
pub mod mmap_fs;
pub mod observer;
pub mod pap;
#[cfg(feature = "parallel")]
pub(crate) mod parallel;
#[cfg(feature = "path-list")]
pub mod path_list;
pub mod phyb;
pub mod route;
pub mod scd;
pub mod sklb;
pub mod sqpack;
pub mod tex;
pub mod tmb;
pub(crate) mod tracing_schema;
pub mod verify;
pub mod vfs;
pub mod write;

// Core API
pub use cancel::CancelToken;
pub use dat::{DatFile, FileKind, SqPackPayload};
pub use error::{Error, Result};
pub use header::Platform;
pub use index::Index;
pub use index2::Index2;
pub use route::Category;
pub use sqpack::SqPack;
pub use vfs::{StdFs, Vfs};

// Decoder handles
pub use eid::Eid;
pub use excel::{Field, Language, Sheet};
pub use mdl::Mdl;
pub use pap::Pap;
pub use phyb::Phyb;
pub use scd::Scd;
pub use sklb::Sklb;
pub use tex::Tex;
pub use tmb::Tmb;

// Write entry points
pub use write::{SqPackAppender, SqPackRepacker};

// Verify entry points
pub use observer::{HashScanObserver, PathVerifyObserver};
pub use verify::{
    SqPackHashManifest, SqPackHashManifestBuilder, SqPackHashVerifier, SqPackPathManifest,
    SqPackPathManifestBuilder, SqPackPathVerifier,
};

// Feature-gated
#[cfg(feature = "block-cache")]
#[cfg_attr(docsrs, doc(cfg(feature = "block-cache")))]
pub use block_cache::BlockCache;
#[cfg(feature = "mmap")]
#[cfg_attr(docsrs, doc(cfg(feature = "mmap")))]
pub use mmap_fs::MmapFs;
#[cfg(feature = "path-list")]
#[cfg_attr(docsrs, doc(cfg(feature = "path-list")))]
pub use path_list::PathList;
