use std::{error::Error, path::PathBuf};
use amaru_kernel::NetworkName;
use include_dir::{Dir, include_dir};
use crate::bootstrap::{BootstrapError, InitialNonces};
pub mod bootstrap;
pub mod exit;
pub mod metrics;
pub mod observability;
pub mod panic;
pub mod tests;
pub mod stages;
pub const SNAPSHOTS_DIR: &str = "snapshots";
pub const DEFAULT_NETWORK: NetworkName = NetworkName::Preprod;
pub const DEFAULT_PEER_ADDRESS: &str = "127.0.0.1:3001";
pub const DEFAULT_LISTEN_ADDRESS: &str = "0.0.0.0:3000";
pub const DEFAULT_CONFIG_DIR: &str = "data";
const SNAPSHOTS_PATH: &str = "snapshots";
const BOOTSTRAP_PATH: &str = "crates/amaru/config/bootstrap";
static BOOTSTRAP_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/config/bootstrap");
pub fn default_ledger_dir(network: NetworkName) -> String {
format!("./ledger.{}.db", network.to_string().to_lowercase())
}
pub fn default_chain_dir(network: NetworkName) -> String {
format!("./chain.{}.db", network.to_string().to_lowercase())
}
pub fn bootstrap_config_dir(network: NetworkName) -> PathBuf {
format!("{}/{}", BOOTSTRAP_PATH, network.to_string().to_lowercase()).into()
}
pub fn default_snapshots_dir(network: NetworkName) -> String {
format!("{}/{}", SNAPSHOTS_PATH, network.to_string().to_lowercase())
}
pub fn default_data_dir(network: NetworkName) -> String {
format!("{}/{}", DEFAULT_CONFIG_DIR, network.to_string().to_lowercase())
}
pub fn default_initial_nonces(network: NetworkName) -> Result<InitialNonces, Box<dyn Error>> {
let default_nonces_file_name = "nonces.json";
let nonces_file = get_bootstrap_file(network, default_nonces_file_name)?
.ok_or(BootstrapError::MissingConfigFile(default_nonces_file_name.into()))?;
Ok(serde_json::from_slice(nonces_file.as_slice())?)
}
pub fn get_bootstrap_file(network: NetworkName, name: &str) -> Result<Option<Vec<u8>>, Box<dyn Error>> {
let path = format!("{}/{}", network.to_string().to_lowercase(), name);
Ok(BOOTSTRAP_DIR.get_file(path).map(|f| f.contents().into()))
}
pub fn get_bootstrap_headers(network: NetworkName) -> Result<impl Iterator<Item = Vec<u8>>, Box<dyn Error>> {
let path = format!("{}/headers/*", network.to_string().to_lowercase());
Ok(BOOTSTRAP_DIR.find(&path)?.filter_map(|f| f.as_file()).map(|f| f.contents().into()))
}
pub mod value_names {
pub const DIRECTORY: &str = "DIR";
pub const ENDPOINT: &str = "HOSTNAME[:PORT]";
pub const FILEPATH: &str = "FILEPATH";
pub const NETWORK: &str = "mainnet|preprod|preview|testnet_<U32>";
pub const POINT: &str = "SLOT.HEADER_HASH";
pub const UINT: &str = "UINT";
pub const UINT_ALL: &str = "UINT|all";
}
pub mod env_vars {
pub const CHAIN_DIR: &str = "AMARU_CHAIN_DIR";
pub const EPOCH: &str = "AMARU_EPOCH";
pub const HEADER_FILE: &str = "AMARU_HEADER_FILE";
pub const HEADERS_DIR: &str = "AMARU_HEADERS_DIR";
pub const LEDGER_DIR: &str = "AMARU_LEDGER_DIR";
pub const LISTEN_ADDRESS: &str = "AMARU_LISTEN_ADDRESS";
pub const MAX_DOWNSTREAM_PEERS: &str = "AMARU_MAX_DOWNSTREAM_PEERS";
pub const MAX_EXTRA_LEDGER_SNAPSHOTS: &str = "AMARU_MAX_EXTRA_LEDGER_SNAPSHOTS";
pub const MIGRATE_CHAIN_DB: &str = "AMARU_MIGRATE_CHAIN_DB";
pub const NETWORK: &str = "AMARU_NETWORK";
pub const NONCES_FILE: &str = "AMARU_NONCES_FILE";
pub const PARENT: &str = "AMARU_PARENT";
pub const PEER_ADDRESS: &str = "AMARU_PEER_ADDRESS";
pub const PID_FILE: &str = "AMARU_PID_FILE";
pub const SNAPSHOT: &str = "AMARU_SNAPSHOT";
pub const SNAPSHOTS_DIR: &str = "AMARU_SNAPSHOTS_DIR";
pub const TARGET_DIR: &str = "AMARU_TARGET_DIR";
}