pub(crate) mod ffi;
pub(crate) mod sock_compat;
pub mod error;
pub mod types;
pub mod protocol;
pub mod role;
pub mod log;
pub mod encoding;
pub mod crypto;
pub mod keypair;
pub mod bls;
pub mod addr;
pub(crate) mod msg;
pub mod server;
pub mod client;
pub mod merkle;
pub mod logindex;
pub mod checkpoint;
pub mod anchor;
pub mod logserver;
pub mod anchorserver;
pub mod trust;
pub mod cache;
pub mod pool;

pub use error::Error;
pub use types::{NodeId, MerkleHash, Tstamp, Duration, Header, Identity};
pub use role::ServerRole;
pub use keypair::Keypair;
pub use bls::{BlsKeypair, BlsPubkey, BlsSig};
pub use addr::{Addr, Url};
pub use checkpoint::Checkpoint;
pub use anchor::AnchorSet;
pub use merkle::{MerkleEntry, MerkleProof, MerkleLog};
pub use logindex::LogIndex;
pub use trust::{TrustStore, TrustSettings, TrustStorage, VerifiedIdentity, Staleness};
pub use cache::{IdentityCache, IdentityCacheSettings, CachedIdentity, CacheStats};
pub use pool::{LogServerPool, PoolSettings, PoolServer, PoolStrategy, ServerHealth};
pub use server::{Server, ServerBuilder, Handler, ResponseWriter, Request, Router, Settings as ServerSettings};
pub use client::{Client, ClientBuilder, Response, Notification};
pub use logserver::{LogServer, LogServerSettings};
pub use anchorserver::{AnchorServer, AnchorServerSettings};

/// Initialize the nwep library. Must be called before any other nwep functions.
pub fn init() -> Result<(), Error> {
    error::check(unsafe { ffi::nwep_init() })
}

/// Return the nwep library version string.
pub fn version() -> &'static str {
    unsafe {
        let ptr = ffi::nwep_version();
        if ptr.is_null() {
            ""
        } else {
            std::ffi::CStr::from_ptr(ptr)
                .to_str()
                .unwrap_or("")
        }
    }
}
