//! # dbc-rs
//!
//! A `no_std` compatible Rust library for parsing and working with DBC (CAN database) files.
//!
//! ## Features
//!
//! - **`no_std` compatible**: Works in embedded environments without the standard library
//! - **Minimal dependencies**: Only `heapless` when using `heapless` feature (zero dependencies with `alloc`/`std`)
//! - **Memory efficient**: Uses `Vec` (via `alloc`) for dynamic collections
//! - **Type-safe**: Strong typing for all DBC elements
//!
//! ## Usage
//!
//! ```rust,no_run
//! use dbc_rs::Dbc;
//!
//! let dbc_content = r#"VERSION "1.0"
//!
//! BU_: ECM TCM
//!
//! BO_ 256 EngineData : 8 ECM
//!  SG_ RPM : 0|16@0+ (0.25,0) [0|8000] "rpm" TCM
//! "#;
//!
//! let dbc = Dbc::parse(dbc_content)?;
//! # Ok::<(), dbc_rs::Error>(())
//! ```

#![cfg_attr(not(feature = "std"), no_std)]
#![deny(unused_must_use)]
#![forbid(unsafe_code)]

#[cfg(feature = "std")]
extern crate std;

#[cfg(all(feature = "alloc", not(feature = "heapless")))]
extern crate alloc;

mod byte_order;
mod compat;
mod dbc;
mod error;
mod extended_multiplexing;
mod message;
mod nodes;
mod parser;
mod receivers;
mod signal;
mod value_descriptions;
mod version;

// Builder infrastructure
// Note: Macros are available in all configurations since they're compile-time only
// and have no runtime dependencies. Builders themselves are std-only.
mod macros;

pub use byte_order::ByteOrder;
pub use dbc::{Dbc, DecodedSignal};
pub use error::{Error, Result};
pub use extended_multiplexing::ExtendedMultiplexing;
pub use message::{Message, Signals};
pub use nodes::Nodes;
pub use receivers::Receivers;
pub use signal::Signal;
pub use value_descriptions::ValueDescriptions;
pub use version::Version;

/// Builders
#[cfg(feature = "std")]
pub use dbc::DbcBuilder;
#[cfg(feature = "std")]
pub use extended_multiplexing::ExtendedMultiplexingBuilder;
#[cfg(feature = "std")]
pub use message::MessageBuilder;
#[cfg(feature = "std")]
pub use nodes::NodesBuilder;
#[cfg(feature = "std")]
pub use receivers::ReceiversBuilder;
#[cfg(feature = "std")]
pub use signal::SignalBuilder;
#[cfg(feature = "std")]
pub use value_descriptions::ValueDescriptionsBuilder;
#[cfg(feature = "std")]
pub use version::VersionBuilder;

pub(crate) use parser::Parser;

/// The version of this crate as specified in `Cargo.toml`.
///
/// This constant is only available when the `std` feature is enabled.
#[cfg(feature = "std")]
pub const PKG_VERSION: &str = env!("CARGO_PKG_VERSION");

// Maximum limits for two-pass parsing (no alloc)
// Note: All MAX_* constants are now defined in limits.rs (generated by build.rs)
// and can be overridden at build time via environment variables:
// - DBC_MAX_MESSAGES (default: 8192, must be power of 2 for heapless)
// - DBC_MAX_SIGNALS_PER_MESSAGE (default: 64)
// - DBC_MAX_NODES (default: 256)
// - DBC_MAX_VALUE_DESCRIPTIONS (default: 64)
// - DBC_MAX_NAME_SIZE (default: 32, per DBC specification)
include!(concat!(env!("OUT_DIR"), "/limits.rs"));

// DBC file format keywords
pub(crate) const VERSION: &str = "VERSION";
pub(crate) const CM_: &str = "CM_";
pub(crate) const NS_: &str = "NS_";
pub(crate) const BS_: &str = "BS_";
pub(crate) const BU_: &str = "BU_";
pub(crate) const BO_: &str = "BO_";
pub(crate) const SG_: &str = "SG_";
pub(crate) const VAL_TABLE_: &str = "VAL_TABLE_";
pub(crate) const BA_DEF_: &str = "BA_DEF_";
pub(crate) const BA_DEF_DEF_: &str = "BA_DEF_DEF_";
pub(crate) const BA_: &str = "BA_";
pub(crate) const VAL_: &str = "VAL_";
pub(crate) const SIG_GROUP_: &str = "SIG_GROUP_";
pub(crate) const SIG_VALTYPE_: &str = "SIG_VALTYPE_";
pub(crate) const EV_: &str = "EV_";
pub(crate) const BO_TX_BU_: &str = "BO_TX_BU_";

// Additional DBC keywords
pub(crate) const VECTOR_INDEPENDENT_SIG_MSG: &str = "VECTOR__INDEPENDENT_SIG_MSG";
pub(crate) const VECTOR_XXX: &str = "Vector__XXX";
pub(crate) const BA_DEF_DEF_REL_: &str = "BA_DEF_DEF_REL_";
pub(crate) const BA_DEF_SGTYPE_: &str = "BA_DEF_SGTYPE_";
pub(crate) const SIGTYPE_VALTYPE_: &str = "SIGTYPE_VALTYPE_";
pub(crate) const ENVVAR_DATA_: &str = "ENVVAR_DATA_";
pub(crate) const SIG_TYPE_REF_: &str = "SIG_TYPE_REF_";
pub(crate) const NS_DESC_: &str = "NS_DESC_";
pub(crate) const BA_DEF_REL_: &str = "BA_DEF_REL_";
pub(crate) const BA_SGTYPE_: &str = "BA_SGTYPE_";
pub(crate) const SGTYPE_VAL_: &str = "SGTYPE_VAL_";
pub(crate) const BU_SG_REL_: &str = "BU_SG_REL_";
pub(crate) const BU_EV_REL_: &str = "BU_EV_REL_";
pub(crate) const BU_BO_REL_: &str = "BU_BO_REL_";
pub(crate) const SG_MUL_VAL_: &str = "SG_MUL_VAL_";
pub(crate) const BA_REL_: &str = "BA_REL_";
pub(crate) const CAT_DEF_: &str = "CAT_DEF_";
pub(crate) const EV_DATA_: &str = "EV_DATA_";
pub(crate) const CAT_: &str = "CAT_";
pub(crate) const FILTER: &str = "FILTER";

#[cfg_attr(not(feature = "std"), allow(dead_code))]
const DBC_KEYWORDS: &[&str] = &[
    VECTOR_INDEPENDENT_SIG_MSG,
    VECTOR_XXX,
    BA_DEF_DEF_REL_,
    BA_DEF_SGTYPE_,
    SIGTYPE_VALTYPE_,
    ENVVAR_DATA_,
    SIG_TYPE_REF_,
    NS_DESC_,
    BA_DEF_REL_,
    BA_SGTYPE_,
    SGTYPE_VAL_,
    VAL_TABLE_,
    SIG_GROUP_,
    SIG_VALTYPE_,
    BO_TX_BU_,
    BU_SG_REL_,
    BU_EV_REL_,
    BU_BO_REL_,
    SG_MUL_VAL_,
    BA_DEF_DEF_,
    BA_DEF_,
    BA_REL_,
    CAT_DEF_,
    EV_DATA_,
    BA_,
    VAL_,
    CM_,
    CAT_,
    NS_,
    BS_,
    BU_,
    BO_,
    SG_,
    EV_,
    VERSION,
    FILTER,
];
