//! Catalog data model: what the otel-plugin records about uploaded SFST files.
//!
//! This crate defines the types (`Catalog`, `CatalogEntry`) and their on-disk
//! serialization: a [`chunk_file::container`] file
//! (magic `NCAT` + version + TOC + crc32) holding a single JSON chunk.
//! It does not perform I/O — writing,
//! uploading, and reconciliation live in later phases of the catalog
//! implementation plan. Query filtering uses [`file_registry::Query`] —
//! the same type the SFST and WAL registries accept, so a single
//! query value flows through the whole planner stack.

pub mod catalog;
pub mod entry;
pub mod registry;

pub use catalog::Catalog;
pub use entry::CatalogEntry;
pub use registry::{File, Registry, filename, parse_stem, scan_max_sequence};

/// Current catalog JSON schema version (the `version` field inside the
/// JSON payload). Distinct from [`CONTAINER_VERSION`], which versions
/// the on-disk framing around it.
///
/// Readers accept exactly this version: a catalog carrying any other value
/// is rejected on recovery (never reused, never migrated) — the version peek
/// happens before the full serde parse, so an unknown schema surfaces as
/// [`Error::UnsupportedVersion`] rather than a serde field error.
pub const FORMAT_VERSION: u32 = 1;

/// Magic bytes of the on-disk catalog container.
pub const CONTAINER_MAGIC: [u8; 4] = *b"NCAT";

/// On-disk container framing version (magic + TOC + per-chunk crc32 via
/// [`chunk_file::container`]). The JSON schema inside the `JSON`
/// chunk is versioned separately by [`FORMAT_VERSION`].
pub const CONTAINER_VERSION: u32 = 1;

#[derive(Debug, thiserror::Error)]
pub enum Error {
    // Wrapper variants are transparent: embedding the source in the message
    // while also chaining it would print it twice in anyhow chains.
    #[error(transparent)]
    Json(#[from] serde_json::Error),

    #[error("unsupported catalog format version: {0}")]
    UnsupportedVersion(u32),

    #[error(transparent)]
    Container(#[from] chunk_file::container::Error),

    #[error(transparent)]
    Io(#[from] std::io::Error),
}
